springboot2中使用@JsonFormat注解不生效怎么解决

2023-05-18,

这篇“springboot2中使用@JsonFormat注解不生效怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springboot2中使用@JsonFormat注解不生效怎么解决”文章吧。

    使用@JsonFormat注解不生效

    百度了不少解决方式,有让用@JsonField,也有让把fastjson去掉的,也有加很多配置的,但是都没用。

    本次使用的版本号

    1、springboot2.2.2 ;

    2、fastjson 1.1.26

    3、<jackson-mapper-asl.version>1.9.10</jackson-mapper-asl.version>     
    <jackson-core.version>2.10.3</jackson-core.version>

    第三点以及相关的依赖可能不需要,加上也没关系

    pom文件中的依赖:

    <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
    <dependency>
                <groupId>org.codehaus.jackson</groupId>
                <artifactId>jackson-mapper-asl</artifactId>
                <version>${jackson-mapper-asl.version}</version>
            </dependency> 
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>${jackson-core.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson-core.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>${jackson-core.version}</version>
            </dependency>

    解决方式

    第一步新建一个转换类 用于自定义Jackson反序列化日期类型时应用的类型转换器,一般用于@RequestBody接受参数时使用

    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 org.apache.commons.lang3.StringUtils;
    import org.apache.commons.lang3.time.DateUtils;
     
    import java.io.IOException;
    import java.text.ParseException;
    import java.util.Date;
     
    /**
     * 自定义Jackson反序列化日期类型时应用的类型转换器,一般用于@RequestBody接受参数时使用
     *  次类是借用网上别的人的,增加了一个日期格式化的类型
     */
    public class DateJacksonConverter extends JsonDeserializer<Date> {
        //此处尤为重要,请查找自己控制台报错的日期格式化类型是啥样的
        //我的是2020-04-29T16:23:44.999Z 所以我在下面的数组中添加了 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" 格式;如果下面数组中没有你要的格式化类型,其他的可自行根据自己的情况去添加即可
        private static String[] pattern =
                new String[]{"yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.S",
                        "yyyy.MM.dd", "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss.S",
                        "yyyy/MM/dd", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss.S", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"};
     
        @Override
        public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
     
            Date targetDate = null;
            String originDate = p.getText();
            if (StringUtils.isNotEmpty(originDate)) {
                try {
                    long longDate = Long.valueOf(originDate.trim());
                    targetDate = new Date(longDate);
                } catch (NumberFormatException e) {
                    try {
                        targetDate = DateUtils.parseDate(originDate, DateJacksonConverter.pattern);
                    } catch (ParseException pe) {
                        throw new IOException(String.format(
                                "'%s' can not convert to type 'java.util.Date',just support timestamp(type of long) and following date format(%s)",
                                originDate,
                                StringUtils.join(pattern, ",")));
                    }
                }
            } 
            return targetDate;
        } 
        @Override
        public Class<?> handledType() {
            return Date.class;
        }
    }

    创建好上边的类之后,如果不想继续,则可以在实体对象属性上加注解就完全可以了。

    导入的包路径为:

    import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
    @JsonDeserialize(using=DateJacksonConverter.class)
    private Date startDate;

    如果不想去让实体类加这个注解,可以在写一个公共配置,如下:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
     
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fx.base.serializer.DateJacksonConverter;
     
    @Configuration
    public class ConverterConfig {
        @Bean
        public DateJacksonConverter dateJacksonConverter() {
            return new DateJacksonConverter();
        }
     
        @Bean
        public Jackson2ObjectMapperFactoryBean jackson2ObjectMapperFactoryBean(
                @Autowired
                        DateJacksonConverter dateJacksonConverter) {
            Jackson2ObjectMapperFactoryBean jackson2ObjectMapperFactoryBean = new Jackson2ObjectMapperFactoryBean();
     
            jackson2ObjectMapperFactoryBean.setDeserializers(dateJacksonConverter);
            return jackson2ObjectMapperFactoryBean;
        }
     
        @Bean
        public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(
                @Autowired
                        ObjectMapper objectMapper) {
            MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter =
                    new MappingJackson2HttpMessageConverter();
            mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
            return mappingJackson2HttpMessageConverter;
        }
    }

    此时就不必再每个实体类属性上加注解了。

    @JsonFormat和@DateTimeFormat的作用

    • @DatetimeFormat是将String转换成Date,一般前台给后台传值时用

        import org.springframework.format.annotation.DateTimeFormat;
        /**
         * 前台传后台时, 字符串自动封装成日期
         */
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date birth;
    • @JsonFormat(pattern=”yyyy-MM-dd”) 将Date转换成String 一般后台传值给前台时

        import com.fasterxml.jackson.annotation.JsonFormat;
        /**
         * 后台返给前台时, 日期自动格式化
         */
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date birth;

    注意:

    @JsonFormat不仅可以完成后台到前台参数传递的类型转换,还可以实现前台到后台类型转换。

    当content-type为application/json时,优先使用@JsonFormat的pattern进行类型转换。而不会使用@DateTimeFormat进行类型转换。

    @JsonFormat注解的作用就是完成json字符串到java对象的转换工作,与参数传递的方向无关。

    以上就是关于“springboot2中使用@JsonFormat注解不生效怎么解决”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注本站行业资讯频道。