springboot学习(八十三) springboot中自定义某个对象的JSON序列化反序列化方式


前言

springboot可自定义JSON序列化和反序列化方式

一、自定义注解

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = CustomSerialize.class)
@JsonDeserialize(using = CustomDeserialize.class)
public @interface CustomStrFormatter {
    // todo 可以定义格式化方式
    String pattern() default "";
}

二、自定义序列化处理

public class CustomSerialize extends JsonSerializer<String> implements ContextualSerializer {
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
        } else {
            TypeReference<List<String>> typeReference = new TypeReference<>() {};
            gen.writeObject(JsonUtils.fromJson(value, typeReference));
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        //判断beanProperty是不是空
        if (property == null){
            return prov.findNullValueSerializer(property);
        }
        //判断类型是否是String
        if (Objects.equals(property.getType().getRawClass(),String.class)){
            CustomStrFormatter annotation = property.getAnnotation(CustomStrFormatter.class);
            if (annotation != null){
                // 这里可以获取注解中的一些参数
                String pattern = annotation.pattern();
                return this;
            }
        }
        return prov.findValueSerializer (property.getType (), property);
    }
}

三、自定义反序列化处理

public class CustomDeserialize extends JsonDeserializer<String> implements ContextualDeserializer {


    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) {
        try {
            if (p != null && StringUtils.isNotEmpty(p.getText())) {
                List<String> strs = new ArrayList<>();
                JsonToken jsonToken;
                while (!p.isClosed() && (jsonToken = p.nextToken()) != null && !JsonToken.FIELD_NAME.equals(jsonToken) &&
                        !JsonToken.END_ARRAY.equals(jsonToken)) {
                    strs.add(p.getValueAsString());
                }
                return JsonUtils.toJson(strs);
            } else {
                return null;
            }
        } catch (Exception e) {
            throw Exceptions.runtimeException(e);
        }
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        //判断beanProperty是不是空
        if (property == null) {
            return ctxt.findNonContextualValueDeserializer(property.getType());
        }
        //判断类型是否是String
        if (Objects.equals(property.getType().getRawClass(), String.class)) {
            CustomStrFormatter annotation = property.getAnnotation(CustomStrFormatter.class);
            if (annotation != null) {
                // 这里可以获取注解中的一些参数
                String pattern = annotation.pattern();
                return this;
            }
        }
        return ctxt.findContextualValueDeserializer(property.getType(), property);
    }
}

四、使用

@RequestMapping("/test/serial")
@RestController
@Slf4j
public class TestJsonFormatterController {

    /**
     * 测试序列化
     * */
    @GetMapping
    public TestModel test1() {
        TestModel testModel = new TestModel();
        testModel.setId("1").setStrs1(List.of("1", "2", "3"))
                .setStrs2("[\"3\", \"4\"]");
        return testModel;
    }

    /**
     * 测试反序列化
     * */
    @PostMapping
    public String test2(@RequestBody TestModel testModel) {
        log.info("接收到的testModel:{}", testModel.toString());
        return "success";
    }

    @Data
    @Accessors(chain = true)
    public static class TestModel {
        private String id;

        private List<String> strs1;

        @CustomStrFormatter
        private String strs2;
    }
}