spring boot中使用jackson,自定义实现序列化和反序列化

spring boot中使用jackson,自定义实现序列化和反序列化

  • 1 自定义序列化的实现
  • 2 应用
    • 2.1 针对某一个字段使用
    • 2.2 全局配置

大部分下,多个程序直接的沟通都离不开序列化和反序列化。前端后端的交互更是如此,所以目前框架提供的很多自带功能都帮我们实现了这些工作。然而!有时候可能遇到来自产品经理或者其他人的奇怪要求,使这些自带功能无法满足,只能自己搞小动作一下了。

1 自定义序列化的实现

这里很简单,就俩

  • 序列化:针对某一数据类型的序列化实现接口JsonSerializer
  • 反序列化:针对某一数据类型的反序列化实现接口JsonDeserializer

这里用时间类型举例吧,换其他类型也同理

序列化实现:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 *
 * @Author: dong
 * @Date: 2023/2/23 17:02
 */
public class MyLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        // 这里是自己的系列化逻辑
        String format = DateTimeFormatter.ofPattern("序列化三侃时间:yyyy-MM-dd HH:mm:ss").format(date);
        // 输处结果,这里注意“writeString”表示写出json的格式。写出的可以是多种格式,自己看具体方法
        jsonGenerator.writeString(format);
    }
}

反序列化实现

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 *
 * @Author: dong
 * @Date: 2023/2/23 17:02
 */
@Slf4j
public class MyLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    private LocalDateTimeDeserializer deserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("反序列化三侃时间:yyyy-MM-dd HH:mm:ss"));
    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        try{
            LocalDateTime localDateTime = deserializer.deserialize(p, ctxt);
            return localDateTime;
        }catch (Exception e){
            log.error("localDateTime类型反序列化失败!val={}",p.getText());
        }
        // 根据自己需求写个兜底的方案
        throw new RuntimeException();
    }
}


2 应用

2.1 针对某一个字段使用

这样使用只对注解的字段生效,不影响其他地方

@Data
    public class Test{

        @JsonSerialize(using = MyLocalDateTimeSerializer.class)
        @JsonDeserialize(using = MyLocalDateTimeDeserializer.class)
        private LocalDateTime param;
    }

2.2 全局配置

当前springboot服务所有LocalDateTime 类型的值序列化都受影响

第一步 实现一个自己的序列化模块

import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
import java.time.LocalDateTime;
// 自定义的序列化模块封装,多种也可以放在一起
public class MyJavaTimeModule extends SimpleModule {



	public MyJavaTimeModule() {
		super(PackageVersion.VERSION);

		// ======================= 时间序列化规则 ===============================
		this.addSerializer(LocalDateTime.class,
				new MyLocalDateTimeSerializer());

		// ======================= 时间反序列化规则 ==============================
		this.addDeserializer(LocalDateTime.class,
				new MyLocalDateTimeDeserializer());
	}

}

第二步 使用这个配置

两种方式都可以

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonConfig {
	@Bean
	public Jackson2ObjectMapperBuilderCustomizer customizer() {
		return builder -> {
			builder.modules(new MyJavaTimeModule());
		};
	}
}

如果自己已经配置实现了WebMvcConfigurer并且有实现extendMessageConverters方法,可以用这种

@Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = converter.getObjectMapper();
        objectMapper.registerModule(new MyJavaTimeModule());
        converters.add(0, converter);
    }


最后看一下效果的

spring boot中使用jackson,自定义实现序列化和反序列化_第1张图片

你可能感兴趣的:(笔记,spring)