0


一文了解Jackson注解@JsonFormat及失效解决

背景

项目中使用

WRITE_DATES_AS_TIMESTAMPS: true

转换日期格式为时间戳未生效。如下:

spring:jackson:time-zone: Asia/Shanghai
    serialization:WRITE_DATES_AS_TIMESTAMPS:true

尝试是否关于时间的注解是否会生效,使用

@JsonForma

@JsonFiled

均失效。

常见失效原因及解决方法

@JsonFormat是用于指定Java对象序列化为JSON字符串时的格式化方式的注解。如果@JsonFormat失效,可能是以下原因:

  1. 未正确导入Jackson库
  2. 注解位置不正确
  3. 注解参数设置错误

解决方法:

  1. 确认是否正确导入了Jackson库,可以在pom.xml文件中添加以下依赖:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.3</version></dependency>

2、确认注解位置是否正确,例如:

publicclassUser{@JsonFormat(pattern ="yyyy-MM-dd")privateDate birthday;// ...}

3、确认注解参数是否正确设置,例如:

@JsonFormat(shape =JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd'T'HH:mm:ss.SSSZ")publicDategetCreatedDate(){return createdDate;}

以上是常见的解决方法,如果还有问题可以提供更具体的错误信息进行排查。

本次问题解决

失效原因

因为项目中使用了Gson替换Jackson。
代码如下:

importcom.google.gson.JsonElement;importcom.google.gson.JsonParser;importcom.google.gson.JsonSerializationContext;importcom.google.gson.JsonSerializer;importspringfox.documentation.spring.web.json.Json;importjava.lang.reflect.Type;publicclassJsonToGsonimplementsJsonSerializer<Json>{@OverridepublicJsonElementserialize(Json json,Type type,JsonSerializationContext context){returnJsonParser.parseString(json.value());}}
@ConfigurationpublicclassSwaggerWebConfigurationimplementsWebMvcConfigurer{@OverridepublicvoidaddResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");}@OverridepublicvoidconfigureMessageConverters(List<HttpMessageConverter<?>> converters){
        converters.removeIf(httpMessageConverter -> httpMessageConverter instanceofMappingJackson2HttpMessageConverter);
        converters.add(gsonHttpMessageConverters());}@BeanpublicGsonHttpMessageConvertergsonHttpMessageConverters(){Gson gson =newGsonBuilder().registerTypeAdapter(Json.class,newSpringfoxJsonToGsonAdapter()).create();GsonHttpMessageConverter gsonConverter =newGsonHttpMessageConverter(gson);return gsonConverter;}}

解决方案一:去掉Gson转换即可。

解决方案二:重新添加MappingJackson2HttpMessageConverter的bean

@Autowired(required =false)privateMappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;@OverridepublicvoidextendMessageConverters(List<HttpMessageConverter<?>> converters){
    converters.removeIf(converter -> converter instanceofMappingJackson2HttpMessageConverter);if(Objects.isNull(mappingJackson2HttpMessageConverter)){
        converters.add(0,newMappingJackson2HttpMessageConverter());}else{
        converters.add(0, mappingJackson2HttpMessageConverter);}}

@Autowired(required =false)privateMappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;@OverridepublicvoidconfigureMessageConverters(List<HttpMessageConverter<?>> converters){
    converters.removeIf(converter -> converter instanceofMappingJackson2HttpMessageConverter);if(Objects.isNull(mappingJackson2HttpMessageConverter)){
        converters.add(0,newMappingJackson2HttpMessageConverter());}else{
        converters.add(0, mappingJackson2HttpMessageConverter);}}

解析

Jackson一直是springframework默认的json库,从4.1开始,springframework支持通过配置GsonHttpMessageConverter的方式使用Gson。

Spring MVC

中,一旦请求退出

@Controller

,它将寻找一个视图来呈现。当指定了

@RequestBody

@RestControlle

r时,我们会告诉Spring跳过这一步,将java对象通过model写入响应结果。Spring通过

HttpMessageConverter

来执行Java对象向其它类型(通常是Json)的转换,Spring默认使用的是

MappingJackson2HttpMessageConverter

,所以如果希望使用Gson来执行这种转换,可用使用

GsonHttpMessageConverter

替换

Jackson

小拓展

在Spring Boot提供了与三个JSON映射库的集成:Gson、默认库 Jackson 、JSON-B

@JsonFormat与@JSONField简介

@JsonFormat

@JsonFormat是Java中的一个Jackson注解,用于指定某个字段或属性,或整个类的JSON序列化或反序列化格式。它允许在将数据类型转换为或从JSON格式转换时自定义日期、数字、布尔值等数据类型的格式。

例如,如果您有一个Java类,其中包含一个Date字段,您希望以特定格式将其序列化为JSON,您可以使用@JsonFormat注解来指定该格式:

示例如下:Jackson在序列化或反序列化myDate字段时使用“yyyy-MM-dd”格式。

publicclassMyClass{@JsonFormat(pattern="yyyy-MM-dd")privateDate myDate;// ...}

@JSONField

@JSONField是阿里巴巴的fastjson库中的一个注解,用于指定Java对象属性在序列化为JSON字符串时的名称、顺序、格式等信息。例如,可以使用@JSONField(name=“username”)指定Java对象属性在序列化为JSON字符串时使用"username"作为属性名。

区别

@JsonFormat和@JSONField都是用于控制Java对象属性在序列化为JSON字符串时的格式,但是它们有一些不同之处。

@JsonFormat是Jackson库中的一个注解,用于指定Java对象属性在序列化为JSON字符串时的日期、时间、数字等格式。例如,可以使用@JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”)指定Java对象属性在序列化为JSON字符串时使用指定的日期时间格式。

@JSONField是阿里巴巴的fastjson库中的一个注解,用于指定Java对象属性在序列化为JSON字符串时的名称、顺序、格式等信息。例如,可以使用@JSONField(name=“username”)指定Java对象属性在序列化为JSON字符串时使用"username"作为属性名。

因此,虽然@JsonFormat和@JSONField都可以用于控制Java对象属性在序列化为JSON字符串时的格式,但是它们的作用范围和使用方式略有不同。

jackson自定义日期注解

依赖HttpMessageConverter默认实现如下:

jackson:MappingJackson2HttpMessageConverter;

请添加图片描述

gson:GsonHttpMessageConverter;

请添加图片描述

fastjson : FastJsonHttpMessageConverter

1、自定义转换类:

publicclassDateToJsonSerializerextendsJsonSerializer<Date>implementsContextualSerializer{privateDateFormat df =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");publicDateToJsonSerializer(){}@Overridepublicvoidserialize(Date arg0,JsonGenerator arg1,SerializerProvider arg2)throwsIOException{if(null!= arg0){
            arg1.writeString(this.df.format(arg0));}}@OverridepublicJsonSerializer<?>createContextual(SerializerProvider prov,BeanProperty property){AnnotationMap annotated = property.getMember().getAllAnnotations();JsonFormat jsonFormat = annotated.get(JsonFormat.class);if(jsonFormat !=null&& jsonFormat.pattern()!=null){
            df =newSimpleDateFormat(jsonFormat.pattern());}returnthis;}}

2、使用

publicclassMyClass{@JsonSerialize(using =DateToJsonSerializer.class)privateDate myDate;// ...}

在这里插入图片描述
翩若惊鸿,婉若游龙。

标签: java spring json

本文转载自: https://blog.csdn.net/qq_35764295/article/details/129718739
版权归原作者 三省同学 所有, 如有侵权,请联系我们删除。

“一文了解Jackson注解@JsonFormat及失效解决”的评论:

还没有评论