当前位置: 首页 > 工具软件 > JsonSerialize > 使用案例 >

SpringBoot使用@JsonDeserialize和@JsonSerialize优雅的处理数据格式

怀晋
2023-12-01

使用SpringMVC,在Controller中接受请求的数据,或者返回数据,有些需要做些特殊的处理。比如说,请求过来的数据是以万为单位的,但是我们需要转化为以元单位的;返回的手机号,中间四位需要以****隐藏。对于这种需求,我们可以手动进行处理。我们也可用@JsonDeserialize和@JsonSerialize来优雅的处理。

@JsonDeserializer

在我做的项目中,遇到这样一种情况,有一组字段,我定义的数据类型是String类型,如果选择了一个,传单个数字;如果多选了,需要用逗号分隔比如1,2,3来传值。但是后来对接的时候,前端那边说,他那边不好处理,多选的,想要传数组。然而,我后边的逻辑都写好了,修改的话,还需要自己手动一个一个的将数组转为逗号分隔的字符串。这样做是可以,但是显得很不优雅。于是我采用了@JsonDeserialize来处理。

首先,需要自定义JsonDeserializer类

public class ParamToStrDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(
            JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
        if (treeNode instanceof IntNode) {
            return ((IntNode) treeNode).asText();
        } else if (treeNode instanceof LongNode) {
            return ((LongNode) treeNode).asText();
        } else if (treeNode instanceof ArrayNode) {
//字符串数组,会多出两个引号,需要手动去除
            return StringUtils.replace(StringUtils.join((ArrayNode) treeNode, ","), "\"", "");
        } else if (treeNode instanceof TextNode) {
            return ((TextNode) treeNode).asText();
        }
        return "";

    }
}

通过ParamToStrDeserializer的转化,无论传的值是数字比如:【1】或者【"1"】;还是数组,比如【[1,2,3]】或者【["1","2","3“]】都能统一转化为用逗号分隔的字符串格式。

然后在需要自动转化的字段上加上注解

@JsonDeserialize(using = ParamToStrDeserializer.class)
private String state;

这样,无论前端传的是哪种格式,state最终都是一种类型了,做到了以不变应万变。

@JsonSerialize

接下来看@JsonSerialize的用法,@JsonDeserialize的反向用法。

public class MyJsonSerializer extends JsonSerializer<List<Integer>> {

    @Override
    public void serialize(
            List<Integer> stateList, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        String join = StringUtils.join(stateList, ",");
        jsonGenerator.writeString(join);

    }
}
@JsonSerialize(using = MyJsonSerializer.class)
private List<Integer> states;

那我们设置的states是个List,但是前端拿到的就是逗号分隔的字符串了。

区别

那这两个有什么区别呢:

@JsonSerialize:json序列化注解,作用于getter()方法,将java对象序列化为json数据。可以理解为用在处理返回的数据

@JsonDeserialize:json反序列化注解,作用于setter()方法,将json数据反序列化为java对象。可以理解为用在处理接收的数据上。

需要注意的是,这两个注解只在json序列化和反序列化的时候触发,其他时候并不生效!

 类似资料: