json序列化时Long类型转换为String类型

将java对象序列化为json对象返回数据给前端时,js处理Long类型数据时会丢失精度,为了解决这种问题,往往给前端返回的Long类型数据要序列化为String类型,前面文章介绍过在springboot中的配置方式 json对象中对Long类型和String类型相互转换。如果接口没有走springboot配置而与其他系统通过进行交互,这时候就需要在json序列化工具内做相应的处理,依照惯例还是分别通过fastjson、gson、jackson三个常用的json序列化工具进行代码演示。

  1. fastjson中可以在属性上添加注解 @JSONField(serializeUsing = ToStringSerializer.class) 实现Long类型转换为String类型:
java 复制代码
@JSONField(serializeUsing = ToStringSerializer.class)
private Long id;

添加上面的注解后再使用fastjson进行序列化时就会把long类型转换为String类型。例如:

java 复制代码
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author: xingo
 * @createDate: 2023/11/30
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DemoVo {

    @JSONField(serializeUsing = ToStringSerializer.class)
    private Long id;
    private String name;
}

测试序列化输出:

java 复制代码
import com.alibaba.fastjson.JSONObject;

/**
 * @author: xingo
 * @createDate: 2023/11/30
 */
public class JsonTest {

    public static void main(String[] args) {
        DemoVo data = DemoVo.builder().id(Long.MAX_VALUE).name("长整型序列化").build();
        String json = JSONObject.toJSONString(data);
        System.out.println(json);
    }
}

输出内容:

json 复制代码
{"id":"9223372036854775807","name":"长整型序列化"}

fastjson也可以在序列化时指定序列化类型,这样就避免在所有字段上添加注解了。删除上面的实体类字段上的注解,改成下面这种方式一样可以实现相同的效果:

java 复制代码
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;

/**
 * @author: xingo
 * @createDate: 2023/11/30
 */
public class JsonTest {

    public static void main(String[] args) {
        DemoVo data = DemoVo.builder().id(Long.MAX_VALUE).name("长整型序列化").build();

        final SerializeConfig config = new SerializeConfig();
        config.put(Long.class, ToStringSerializer.instance);
        String json = JSONObject.toJSONString(data, config);
        System.out.println(json);
    }
}
  1. jackson与fastjson类似,可以通过在属性上添加注解实现Long类型转换为String类型:
java 复制代码
@JsonSerialize(using = ToStringSerializer.class)
private Long id;

使用jackson进行序列化测试:

java 复制代码
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author: xingo
 * @createDate: 2023/11/30
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DemoVo {

    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
    private String name;
}
java 复制代码
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @author: xingo
 * @createDate: 2023/11/30
 */
public class JsonTest {

    public static void main(String[] args) throws JsonProcessingException {
        DemoVo data = DemoVo.builder().id(Long.MAX_VALUE).name("长整型序列化").build();

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(data);
        System.out.println(json);
    }
}

测试输出:

json 复制代码
{"id":"9223372036854775807","name":"长整型序列化"}

jackson中还可以在序列化工具上面添加相关配置实现Long类型序列化为String,这样就不用在每一个字段上都添加相关配置。将上面实体类中的注解删除,改成下面这种方式进行测试:

java 复制代码
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

/**
 * @author: xingo
 * @createDate: 2023/11/30
 */
public class JsonTest {

    public static void main(String[] args) throws JsonProcessingException {
        DemoVo data = DemoVo.builder().id(Long.MAX_VALUE).name("长整型序列化").build();

        ObjectMapper mapper = new ObjectMapper();
        // 指定字段序列化类型
        SimpleModule module = new SimpleModule();
        module.addSerializer(Long.class, ToStringSerializer.instance);
        mapper.registerModule(module);

        String json = mapper.writeValueAsString(data);
        System.out.println(json);
    }
}
  1. gson与上面的两个工具对比,没有提供在字段上添加注解的方式实现序列化时类型转换,它可以通过在实例上添加相关的配置实现相同的功能。
java 复制代码
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;

/**
 * @author: xingo
 * @createDate: 2023/11/30
 */
public class JsonTest {

    public static void main(String[] args) {
        DemoVo data = DemoVo.builder().id(Long.MAX_VALUE).name("长整型序列化").build();

        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Long.class, new TypeAdapter<Long>() {
                    @Override
                    public void write(JsonWriter writer, Long l) throws IOException {
                        if(l != null) {
                            writer.value(String.valueOf(l));
                        } else {
                            writer.nullValue();
                        }
                    }

                    @Override
                    public Long read(JsonReader reader) throws IOException {
                        return reader.nextLong();
                    }
                })
                .create();

        String json = gson.toJson(data);
        System.out.println(json);
    }
}

输出内容:

json 复制代码
{"id":"9223372036854775807","name":"长整型序列化"}

以上总结的几种处理方案可以在项目中灵活选择,如果要影响范围小,就选择在需要处理的字段上面添加注解的方式;如果在项目中所有用到的地方都想使用,就通过在工具类上面做相关的配置全局生效。

相关推荐
Ashley_Amanda5 小时前
JavaScript 中 JSON 的处理方法
前端·javascript·json
Lxinccode7 小时前
python(67) : json解析异常json.decoder.JSONDecodeError
json·json解析·json解析报错·jsondecodeerror
Violet_YSWY8 小时前
我要生成上边是表头,左边是平均值、方差等的表格如何json
json
小北方城市网12 小时前
第7课:Vue 3应用性能优化与进阶实战——让你的应用更快、更流畅
前端·javascript·vue.js·ai·性能优化·正则表达式·json
吃喝不愁霸王餐APP开发者14 小时前
使用Mockito与WireMock对美团霸王餐接口进行契约测试与集成验证
java·json
chilavert31815 小时前
技术演进中的开发沉思-268 Ajax:JSON
javascript·ajax·okhttp·json
Cv打怪升级17 小时前
3D-Front数据集 json说明
3d·json
电商API&Tina1 天前
【电商API接口】关于电商数据采集相关行业
java·python·oracle·django·sqlite·json·php
天远数科1 天前
Go语言金融风控:天远 全能小微企业报告组合接口的 AES 加密与异构 JSON 解析
大数据·golang·json
盼哥PyAI实验室2 天前
Python 爬虫核心基础:请求与响应机制全解析(从 GET 请求到 JSON 分页实战)
爬虫·python·json