自定义全局jackson序列化

本文介绍如何在SpringMVC项目中自定义JSON格式化工具,实现统一处理日期和null值的序列化,简化开发流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述在WEB开发中前后台使用JSON传输,难免前后台格式的转换的问题。以下是以SPRINGMVC开发为例说明

如:日期的转换;null的转换等

 

1:自定义一个继承ObjectMapper的类

Java代码  收藏代码
  1. /** 
  2.  * 自定义的JSON转换MAPPER 
  3.  * @author xixi 
  4.  * @date 2013-6-24 
  5.  * 
  6.  */  
  7. public class CustomObjectMapper extends ObjectMapper {  
  8.   
  9.     public CustomObjectMapper(){  
  10.         super();  
  11.         //设置null转换""  
  12.         getSerializerProvider().setNullValueSerializer(new NullSerializer());  
  13.         //设置日期转换yyyy-MM-dd HH:mm:ss  
  14.         setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));  
  15.     }  
  16.       
  17.     //null的JSON序列  
  18.     private class NullSerializer extends JsonSerializer<Object> {  
  19.         public void serialize(Object value, JsonGenerator jgen,  
  20.                 SerializerProvider provider) throws IOException,  
  21.                 JsonProcessingException {  
  22.             jgen.writeString("");  
  23.         }  
  24.     }  
  25. }  

 2:在spring的配置文件中定义这个自定义的Mapper

Xml代码  收藏代码
  1. <!-- 启动 MVC注解 -->  
  2. <mvc:annotation-driven>  
  3.     <mvc:message-converters>  
  4.         <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
  5.             <property name="objectMapper" ref="customObjectMapper" />  
  6.         </bean>  
  7.     </mvc:message-converters>  
  8. </mvc:annotation-driven>  
  9.   
  10. <!-- 自定义的JSON ObjectMapper -->  
  11. <bean id="customObjectMapper" class="com.xixi.web4j.util.CustomObjectMapper" />  

 就这么简单,不用再像每个POJO对像上去@JsonSerializer(using...)了。

以后对所有DATE类型字段序列化JSON,都会默认传为“yyyy-MM-dd HH:mm:ss”格式,对于字段为null的也会转为“”。如果你对null有别的处理。你可以在自定义的NullSerializer修改你想要的格式。

<think>我们在处理一个关于SpringBootJackson自定义注解实现序列化字段重命名的问题。根据用户的问题,他希望在序列化时通过自定义注解来重命名字段。参考引用:引用[1]展示了SpringBoot中Jackson自动配置的一部分代码,它通过反射设置PropertyNamingStrategy,这可以启发我们如何自定义命名策略。引用[2]提到了自定义注解并忽略序列化,但用户的需求是重命名,而不是忽略。不过,自定义注解的思路是一致的。引用[3]强调了理解Jackson基础的重要性,因此我们应确保解决方案基于Jackson的核心功能。实现思路:1.自定义一个注解(例如@JsonRename),用于标注需要重命名的字段,并指定序列化后的字段名。2.自定义一个Jackson模块(SimpleModule),并注册一个自定义的BeanSerializerModifier,在修改序列化器时检查字段上的自定义注解,然后重命名字段。3.或者,我们可以利用PropertyNamingStrategy,但引用[1]中是通过设置整个策略,而策略是全局的,不适合部分字段重命名。因此,采用自定义序列化器或修改序列化过程的方式更合适。步骤:步骤1:创建自定义注解@JsonRename步骤2:创建自定义的BeanSerializerModifier,在修改序列化器时,遍历所有属性,检查是否有@JsonRename注解,如果有,则修改该属性的名称。步骤3:将自定义模块注册到ObjectMapper中。但是,在SpringBoot中,我们可以通过自定义Jackson2ObjectMapperBuilderCustomizer来配置ObjectMapper。注意:我们还可以考虑使用@JsonSerialize注解配合自定义序列化器,但那样需要为每个字段写一个序列化器,不够灵活。而通过BeanSerializerModifier可以在一个地方统一处理。实现:1.定义注解:```javaimportjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public@interfaceJsonRename{Stringvalue();//指定序列化后的名称}```2.创建自定义的BeanSerializerModifier:```javaimportcom.fasterxml.jackson.databind.BeanDescription;importcom.fasterxml.jackson.databind.SerializationConfig;importcom.fasterxml.jackson.databind.ser.BeanPropertyWriter;importcom.fasterxml.jackson.databind.ser.BeanSerializerModifier;importjava.util.List;importjava.util.stream.Collectors;publicclassRenameAnnotationBeanSerializerModifierextendsBeanSerializerModifier{@OverridepublicList<BeanPropertyWriter>changeProperties(SerializationConfigconfig,BeanDescriptionbeanDesc,List<BeanPropertyWriter>beanProperties){//遍历所有属性returnbeanProperties.stream().map(writer->{JsonRenameannotation=writer.getAnnotation(JsonRename.class);if(annotation!=null){//如果有注解,则重命名字段returnnewBeanPropertyWriter(writer){@OverridepublicStringgetName(){returnannotation.value();}};}returnwriter;}).collect(Collectors.toList());}}```3.创建自定义模块并注册修改器:```javaimportcom.fasterxml.jackson.databind.module.SimpleModule;publicclassCustomJacksonModuleextendsSimpleModule{publicCustomJacksonModule(){setSerializerModifier(newRenameAnnotationBeanSerializerModifier());}}```4.在SpringBoot中配置Jackson:我们可以通过自定义Jackson2ObjectMapperBuilderCustomizer来添加自定义模块,或者直接通过Bean声明。```javaimportorg.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassJacksonConfig{@BeanpublicCustomJacksonModulecustomJacksonModule(){returnnewCustomJacksonModule();}//或者使用Jackson2ObjectMapperBuilderCustomizer@BeanpublicJackson2ObjectMapperBuilderCustomizerjacksonCustomizer(){returnbuilder->builder.modules(customJacksonModule());}}```5.使用示例:```javapublicclassUser{@JsonRename("userName")privateStringname;//gettersandsetters}```在序列化User对象时,原本的字段"name"将会被重命名为"userName"。注意事项:这种方法覆盖了`BeanPropertyWriter`的`getName`方法,只修改了字段在序列化时使用的名称。如果还有其他需求(如反序列化),则需要另外处理。由于我们的需求仅限于序列化重命名,因此此方案是合适的。引用参考:[1]中的代码展示了SpringBoot内部如何使用反射设置命名策略,我们的方法与其类似,都是通过修改Jackson的配置来实现定制化。[2]中自定义注解的思路被我们采纳,但用于不同的目的(重命名而非忽略)。[3]提醒我们,理解Jackson基础很重要。这里我们使用了Jackson的`BeanSerializerModifier`来修改序列化行为,这是Jackson进阶内容。因此,按照上述步骤,用户可以实现通过自定义注解在序列化时重命名字段。生成相关问题:1.如何让这个自定义注解同时支持反序列化的字段重命名?2.除了重命名,自定义注解还能控制Jackson的哪些序列化行为?3.在SpringBoot中有没有更简洁的方法实现字段重命名?4.如何确保自定义Jackson配置不会影响其他模块的序列化/反序列化?</think> ### Spring Boot中使用Jackson通过自定义注解实现序列化字段重命名 在Spring Boot中,可以通过以下步骤实现基于自定义注解的字段重命名: --- #### 1. **创建自定义注解** 定义注解`@JsonPropertyRename`,用于标记需要重命名的字段: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface JsonPropertyRename { String value(); // 指定序列化后的新字段名 } ``` --- #### 2. **实现序列化修改器** 创建`CustomSerializerModifier`修改序列化行为,动态应用重命名规则: ```java import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; import java.util.List; public class CustomSerializerModifier extends BeanSerializerModifier { @Override public List<BeanPropertyWriter> changeProperties( SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) { for (BeanPropertyWriter writer : beanProperties) { JsonPropertyRename annotation = writer.getAnnotation(JsonPropertyRename.class); if (annotation != null) { writer.rename(annotation.value()); // 重命名字段 } } return beanProperties; } } ``` --- #### 3. **注册Jackson自定义模块** 在Spring Boot配置中注册自定义模块: ```java import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JacksonConfig { @Bean public SimpleModule customJacksonModule() { SimpleModule module = new SimpleModule(); module.setSerializerModifier(new CustomSerializerModifier()); return module; } } ``` --- #### 4. **使用注解重命名字段** 在实体类中标记需重命名的字段: ```java public class User { @JsonPropertyRename("user_id") private Long id; // 序列化后字段名为user_id @JsonPropertyRename("full_name") private String name; // 序列化后字段名为full_name } ``` --- #### 5. **序列化效果** 对象`new User(1, "Alice")`序列化为JSON: ```json { "user_id": 1, "full_name": "Alice" } ``` --- ### 实现原理分析 1. **注解扫描** `BeanSerializerModifier`在序列化前扫描所有字段的`JsonPropertyRename`注解[^1]。 2. **动态重命名** 通过覆盖`BeanPropertyWriter.rename()`修改字段序列化名称,保持Jackson核心逻辑不变[^3]。 3. **Spring Boot整合** 自定义模块自动被`JacksonAutoConfiguration`加载到`ObjectMapper`[^1]。 --- ### 注意事项 1. 此方案**仅影响序列化**(对象转JSON),反序列化需单独处理 2. 优先使用Jackson原生注解`@JsonProperty`,除非需要复杂逻辑 3. 与`PropertyNamingStrategy`共存时,自定义注解优先级更高 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值