spring(一) spring-json全局序列化

场景介绍

后台传送数据给前端,一般使用json ,多的不说,看个例子:

如果使用mongodb数据库,非常容易出现一种状况, 在传送ObjectId (默认数据可以的主键)时会发生如下情况:

  data :{
    objectId :{
        timestamp:123123123,
        machineIdentifier: 12,
        processIdentifier: 12,
        counter:5 6,
    },
    name:“张三”
  }

问题出现了,ObjectId 前端只是要我们说传递一个字符串(ObjectId的),而我们却传递了一个对象,前端肯定会(你懂的!!!)

解决方式

方式一:注解加入

  1. 写一个应对ObjectId的json序列化类,将序列化的函数重写
public class ObjectIdSerializer extends JsonSerializer<ObjectId> {
    
    @Override
    public void serialize(ObjectId value, JsonGenerator jsonGen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        jsonGen.writeString(value.toString());
    }
}
  1. 在需要导出的java 类中的 ObjectId的属性上加注解,示例如下:
Class User{
    @JsonSerialize(using = ObjectIdSerializer.class)
    private ObjectId id;
    private String name;
}

优势:可以解决问题 <br> 缺点:整个项目但凡要 传递给前端的,都需要加入整个注解

方式二:全局配置

全局配置是要带 方式一 第一个步骤的基础之上的,具体操作如下:

  1. 创建自定义ObjectMapper类,如下所示:
@SuppressWarnings("serial")
public class ObjectIdMapper extends ObjectMapper {
    
    public ObjectIdMapper() {
        SimpleModule module = new SimpleModule("ObjectIdmodule");
        module.addSerializer(ObjectId.class, new ObjectIdSerializer());
        this.registerModule(module);
    }

}
  1. ssm 项目,spring配置文件中加入以下配置(springboot项目直接配置Bean 就好了):
<bean id="mappingJackson2HttpMessageConverter"
            class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes">
        <list>
            <value>text/html;charset=UTF-8</value>
        </list>
    </property>
    <!-- <property name="objectMapper">
         <bean class="com.ftf.clw.dsc.web.convert.ObjectIdMapper"></bean>
     </property> -->
</bean>

3)springboot 项目,直接加入一个配置bean 就好了,配置如下

@Configuration
public class JsonMessageConverter {

    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder){
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();

        //将json属性的空值null转化为空字符串""
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                gen.writeString("");
            }
        });

        SimpleModule module = new SimpleModule();
        module.addSerializer(ObjectId.class, new ObjectIdSerializer());
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

测试结果

   data :{
    objectId :"jjaiaiajiaiaiajaldkdkdkdkdkdkdd",
    name:“张三”
  } 

底层剖析

使用的是java序列化的开源jar, Jackson <br>

jackson参见 <br> springboot 修改序列化工具 Jackson 改为 FastJson <br>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的 LocalDateTime 序列化序列化全局配置类示例: ```java import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.time.LocalDateTime; @Configuration public class LocalDateTimeConfig { @Bean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer()); objectMapper.registerModule(javaTimeModule); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); return objectMapper; } } ``` 在上面的代码中,我们首先创建了一个 `ObjectMapper` 对象,并添加了 `JavaTimeModule` 模块,该模块包含了序列化和反序列化 `LocalDateTime` 对象的方法。然后我们将此 `ObjectMapper` 注册到 Spring全局配置中,并关闭了时间戳的序列化。 接下来我们需要自定义 `LocalDateTimeSerializer` 和 `LocalDateTimeDeserializer` 类来实现 `LocalDateTime` 的序列化和反序列化: ```java 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; public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> { private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; @Override public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(formatter.format(value)); } } ``` ```java import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> { private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; @Override public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { return LocalDateTime.parse(p.getValueAsString(), formatter); } } ``` 现在,我们就可以使用 `LocalDateTime` 类型的属性在 RESTful API 中进行序列化和反序列化了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值