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;
}
}