原创GrayHJX 发布于2017-03-14 22:56:33 阅读数 6851  收藏

问题:最近在工作中遇到这么一个问题:有个实体类,它有个date类型的属性,当在这个属性加上fastjson的注解@JSONField (format=”yyyy-MM-dd HH:mm”)将秒去掉后,对象转换成json字符串,再用这个字符串反过来转换成对象的时候去报错了。如图所示:

查看源码后得知是fastjson在处理这个日期格式时并没有考虑到这个问题。好在fastjson可以扩展,我们可以通过继承DateFormatDeserializer去实现我们自己的反序列化器来解析这个格式。
记录一下解决办法以便今后查询,当然,这不一定就是正确的解决办法,如果有更好的解决办法欢迎给我留言。


解决办法:我们要自己去实现自己的Deserializer
这里我取了个巧,参考了fastjson的util包中TypeUtils类的castToDate方法了。。。。

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.deserializer.DateFormatDeserializer; import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; /**
* Created by gray on 2017/3/12.
*/
public class MyDateFormatDeserializer extends DateFormatDeserializer {
@Override
protected <T> T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object value) {
if(value == null) {
return null;
} else if(value instanceof Calendar) {
return (T) ((Calendar)value).getTime();
} else if(value instanceof Date) {
return (T) value;
} else {
long longValue = -1L;
if(value instanceof Number) {
longValue = ((Number)value).longValue();
return (T) new Date(longValue);
} else {
if(value instanceof String) {
String strVal = (String)value;
if(strVal.indexOf(45) != -1) {
String format;
if(strVal.length() == 10) {
format = "yyyy-MM-dd";
} else if(strVal.length() == "yyyy-MM-dd HH:mm".length()) {
format = "yyyy-MM-dd HH:mm";
} else if(strVal.length() == "yyyy-MM-dd HH:mm:ss".length()) {
format = "yyyy-MM-dd HH:mm:ss";
} else {
format = "yyyy-MM-dd HH:mm:ss.SSS";
} SimpleDateFormat dateFormat = new SimpleDateFormat(format); try {
return (T) dateFormat.parse(strVal);
} catch (ParseException var7) {
throw new JSONException("can not cast to Date, value : " + strVal);
}
} if(strVal.length() == 0) {
return null;
} longValue = Long.parseLong(strVal);
} if(longValue < 0L) {
throw new JSONException("can not cast to Date, value : " + value);
} else {
return (T) new Date(longValue);
}
}
}
}
}

测试:在我们要使用的地方这么写,如下代码:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig; import java.util.Date; /**
* Created by gray on 2017/3/12.
*/
public class Test {
static ParserConfig config = new ParserConfig(); public static void main(String args[]) {
String json = "{oneDate:'2017-03-14 20:25',twoDate:'2017-03-14 21:30:12',text:'test'}";
config.putDeserializer(Date.class, new MyDateFormatDeserializer()); // 我们自己实现的Deserializer
TestBean bean = JSON.parseObject(json,TestBean.class, config, JSON.DEFAULT_PARSER_FEATURE, new Feature[0]);
System.out.print(bean.toString());
}
}

parseObject这个方法平时我们用得多的就是String和class两个参数,其实它后面会默认调用多参的方法,放入默认的配置而已。这样写然后运行结果就正确了,MyDateFormatDeserializer里面该处理的格式都处理清楚就不会影响别的date格式了(onedate和twodate格式互不影响,如果你的MyDateFormatDeserializer只处理了”yyyy-MM-dd HH:mm”这一种格式会导致twodate的精度丢失)。运行结果如图所示:

最后附上TestBean

import java.util.Date;

/**
* Created by gray on 2017/3/12.
*/
public class TestBean {
private Date oneDate;
private Date twoDate;
private String text; public Date getOneDate() {
return oneDate;
} public void setOneDate(Date oneDate) {
this.oneDate = oneDate;
} public Date getTwoDate() {
return twoDate;
} public void setTwoDate(Date twoDate) {
this.twoDate = twoDate;
} public String getText() {
return text;
} public void setText(String text) {
this.text = text;
} @Override
public String toString() {
return "TestBean{" +
"oneDate=" + oneDate +
", twoDate=" + twoDate +
", text='" + text + '\'' +
'}';
}
}

fastjson对于yyyy-MM-dd HH:mm格式的反序列化问题的更多相关文章

  1. 小程序日期格式(yyyy-MM-dd HH:mm:ss)转(yyyy/MM/dd HH:mm:ss)

    let newDate = (date).replace(/-/g, '/'); var date = new Date(newDate).getTime();

  2. java 日期格式转换EEE MMM dd HH:mm:ss z yyyy

    SimpleDateFormat parserSDF = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzzz yyyy", Locale. ...

  3. js 时间YYYY-MM-DD转换为YYYY/MM/DD 自定义函数格式

    <script type="text/javascript">         window.onload = function () {             va ...

  4. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

    java日期格式大全 format SimpleDateFormat(转) SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH ...

  5. javascript:针对yyyy-MM-dd hh:mm:ss格式的毫秒转换.

    javascript:针对yyyy-MM-dd hh:mm:ss格式的毫秒转换. 时间 2015-11-07 22:18:39  HideHai's blog 原文  http://www.hideh ...

  6. 火狐低版本中显示时间格式为:yyyy-MM-dd hh:mm:ss,出现NaN

    在低版本的火狐(43以下)和IE8中,显示时间格式为:yyyy-MM-dd hh:mm:ss,会出现NaN:原因是只支持yyyy/MM/dd hh:mm:ss; 所以在new Date('2018-0 ...

  7. js转换时间戳-转换成 yyyy-MM-dd HH:mm:ss

    比如:转换成 yyyy-MM-dd HH:mm:ss //时间戳转换方法 date:时间戳数字 function formatDate(date) { var date = new Date(date ...

  8. vue-cli 利用moment.js转化时间格式为YYYY年MM月DD日,或者是YYYY-MM-DD HH:MM:SS 等格式

    1.在mian.js引入moment import moment from 'moment' Vue.prototype.$moment = 'moment' 2. 在main.js 设置全局过滤器 ...

  9. dd/MMM/yyyy:hh:mm:ss +0800日期格式的转化

    private static void myHandler() throws ParseException { String dtime1 = "23/Apr/2019:04:08:00 + ...

  10. JAVA 时间"dd/MMM/yyyy:HH:mm:ss Z", Locale.US

    工作遇到时间格式转换问题, 就是在日志分析时, 需要将格式“15/Oct/2009:14:00:00 +0800”转为格式“2009-10-15 14:00:00”, 找了好久没有找到合适的,终于在友 ...

随机推荐

  1. .net core 在 Docker 上的部署

    Docker可以说是现在微服务,DevOps的基础,咱们.Net Core自然也得上Docker..Net Core发布到Docker容器的教程网上也有不少,但是今天还是想来写一写.你搜.Net co ...

  2. Python 周刊第 418 期

    新闻 PyCon US 2020 开始接受财务赞助! https://pycon.blogspot.com/2019/10/financial-aid-launches-for-pycon-us-20 ...

  3. ETC到底要不要办?有什么好处?

    一说到ETC,开车的朋友想必不会陌生.但很多车友却不太愿意办理ETC, 究其原因,主要是一些谣言所致,一传一十传百最后变成了真实的谎言,并且对此深信不疑, 比如下面5个广泛流传的谣言     在来看看 ...

  4. go语言之数组

    1.go语言的数组和python的列表不一样,python的列表没有限定类型,而go的数组限定的类型,理由是这样的,请看下面的图 go语言的数组会数组中第一个值的内存地址,在我们上面的例子中,数组中的 ...

  5. Java每日一面(Part1:计算机网络)[19/10/14]

    作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 1.1 说一说TCP的四次挥手 ​ "挥手",即终止TCP连接,断开一个TCP连接池. ​ 需要客户端和服务端总共发出四个包,以 ...

  6. 【SDUT】【链表】2120 - 数据结构实验之链表五:单链表的拆分

    Problem Description 输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数.两个子链表中数据的相对次序与原链表一致. ...

  7. Java生鲜电商平台-电商虚拟币的充值与消费思考

    Java生鲜电商平台-电商虚拟币的充值与消费思考 项目背景 最近由于项目业务原因,需要为系统设计虚拟币的充值及消费功能.公司内已经有成熟的支付网关服务,所以重点变成了如何设计项目内虚拟币的充值流程,让 ...

  8. .netcore 文件上传转为base64位字符串

    .netcore文件上传Api接口,和正常的webForm提交类似,只是用postman测试接口时,记得给form表单命名,否则获取上传文件数量一直为0 后端代码 using System; usin ...

  9. javascript 模块化开发(一)

    什么是模块化 将一组模块(及其依赖项)以正确的顺序拼接到一个文件(或一组文件)中的过程. 传统的模块化做法. 模块是实现特定功能的一组属性和方法的封装. 将模块写成一个对象,所有的模块成员都放到这个对 ...

  10. HbaseShell启动

    找到hbase目录 进入bin目录 ./hbase shell 成功