码迷,mamicode.com
首页 > 编程语言 > 详细

JSON parse error: default constructor not found. class java.time.YearMonth; nested exception is com.alibaba.fastjson.JSONException: default constructor not found. class java.time.YearMonth

时间:2020-02-18 13:23:03      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:over   post请求   res   error:   函数   公有   col   ret   mic   

java8新出的YearMonth可以方便的用来表示某个月。我的项目中使用springmvc来接收YearMonth类型的数据时发现 x-www-from-urlencoded 格式的数据可以使用"2018-12"的类型接收,但是在post请求中 接收application/json的数据时出现以下错误                                              

2020-02-18 11:18:25.284 WARN 16212 --- [nio-8090-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: default constructor not found. class java.time.YearMonth; nested exception is com.alibaba.fastjson.JSONException: default constructor not found. class java.time.YearMonth;

 

通过异常应该是YearMonth没有公有构造函数 ,fastjson不支持解析YearMonth;案例使用fastjson作为了springmvc的序列化工具,类似如下的配置

@Configuration
public class MyConverter implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        converters.add(0,fastJsonHttpMessageConverter);
    }
}

通过查看MonthYear确实发现其私有化了构造函数,只留了两静态方法

    private YearMonth(int year, int month) {
        this.year = year;
        this.month = month;
    }
    public static YearMonth of(int year, int month) {
        YEAR.checkValidValue(year);
        MONTH_OF_YEAR.checkValidValue(month);
        return new YearMonth(year, month);
    }
    private YearMonth with(int newYear, int newMonth) {
        if (year == newYear && month == newMonth) {
            return this;
        }
        return new YearMonth(newYear, newMonth);
    }

 

 

不过get请求时能获取得到,说明jackson应该是对其有专门的处理工具的。将springmvc的序列化工具修改为默认的jackson,发现能 将application/json请求中 “2018-12”格式的数据  顺利的反序列化YearMonth类型。然后通过查找发现jackson确实带有YearMonth的序列化反序列化工具

技术图片

 

 (看来springmvc将jackson作为默认序列化工具还是有原因的。。)

所以解决方法看来也找到了。就是使用默认的jackson作为序列化工具就可以解决了。

当然了,如果项目不好更改,想使用fastjson也有解决办法。fastjson允许为字段定制反序列化工具,然后对应字段标明使用指定的反序列化类即可  (序列化原理类似)

public class YearMonthDeserializer implements ObjectDeserializer {
    @Override
    public YearMonth deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
        return YearMonth.parse(parser.getLexer().stringVal());
    }

    @Override
    public int getFastMatchToken() {
        return 0;
    }
}
public class AddVO {

    @JSONField(deserializeUsing = YearMonthDeserializer.class)
    private YearMonth yearMonth;

    public YearMonth getYearMonth() {
        return yearMonth;
    }

    public void setYearMonth(YearMonth yearMonth) {
        this.yearMonth = yearMonth;
    }
}

 

JSON parse error: default constructor not found. class java.time.YearMonth; nested exception is com.alibaba.fastjson.JSONException: default constructor not found. class java.time.YearMonth

标签:over   post请求   res   error:   函数   公有   col   ret   mic   

原文地址:https://www.cnblogs.com/hetutu-5238/p/12325457.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!