fastjson对Timestamp的处理 解决:For input string: "2019-10-21 14:05:21"
场景:fastjson处理json与java对象转换十分方便,现在有需求需要使用fastjson的 JSON.toJavaObject(json,clazz)方法
将json数据转为SubReport对象,
SubReport subReport = JSON.toJavaObject(json, SubReport.class);
,其中SubReport的时间对象使用的是java.sql.TimeStamp,转换过程中抛出异常For input string: "2019-10-21 14:05:21"。
解决方法:
将字符串转化为java.util.Date,然后交给fastjson进行转换即可,代码如下:
public static void testJson() throws Exception{
JSONObject json = new JSONObject();
json.put("addtime","2019-10-21 14:05:21");
json.put("edittime","2019-09-21 14:05:22");
json.put("addUsername","张飞");
json.put("editUsername","赵云");
//将字符串形式的时间,转为Date格式,fastjson内部支持Date转TimeStamp
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date addtime = sdf.parse(json.getString("addtime"));
json.put("addtime",addtime);
System.out.println("转换前参数:"+json.toJSONString());
SubReport subReport = JSON.toJavaObject(json, SubReport.class);
System.out.println("转换后修改时间为:"+subReport.getEdittime());
System.out.println("转换后添加时间为:"+subReport.getAddtime());
System.out.println("对象转json:"+JSON.toJSONString(subReport));
}
代码及原理 :
SubReport 对象为:
package com.putorn.powerdoc.entity;
import com.alibaba.fastjson.annotation.JSONField;
import java.sql.Timestamp;
import java.util.Date;
public class SubReport {
// 添加人id
private Integer addUserid;
// 添加人姓名
private String addUsername;
// 添加时间
@JSONField(format="yyyy-MM-dd HH:mm:ss")
private Timestamp addtime;
// 修改人id
private Integer editUserid;
// 修改人姓名
private String editUsername;
// 修改时间
@JSONField(format="yyyy-MM-dd HH:mm:ss")
private Date edittime;
public Integer getAddUserid() {
return addUserid;
}
public void setAddUserid(Integer addUserid) {
this.addUserid = addUserid;
}
public String getAddUsername() {
return addUsername;
}
public void setAddUsername(String addUsername) {
this.addUsername = addUsername;
}
public Timestamp getAddtime() {
return addtime;
}
public void setAddtime(Timestamp addtime) {
this.addtime = addtime;
}
public Integer getEditUserid() {
return editUserid;
}
public void setEditUserid(Integer editUserid) {
this.editUserid = editUserid;
}
public String getEditUsername() {
return editUsername;
}
public void setEditUsername(String editUsername) {
this.editUsername = editUsername;
}
public Date getEdittime() {
return edittime;
}
public void setEdittime(Date edittime) {
this.edittime = edittime;
}
}
跟踪fastjson源码,可以找到内部转换时对Timestamp的处理方法(具体代码追踪需耐心查看并理解,下面只给出源码及与本问题相关的代码注释):com\alibaba\fastjson\1.2.12\fastjson-1.2.12.jar!\com\alibaba\fastjson\util\TypeUtils.class 第430行:
/**
*这是fastjson内部转换TimeStamp类型的数据时使用的,当反射获取的java类字段类型为 java.sql.Timestamp时,转换调用此方法
*/
public static java.sql.Timestamp castToTimestamp(Object value) {
if (value == null) {
return null;
}
//支持日历类转换
if (value instanceof Calendar) {
return new java.sql.Timestamp(((Calendar) value).getTimeInMillis());
}
if (value instanceof java.sql.Timestamp) {
return (java.sql.Timestamp) value;
}
//如果是Date类型,则直接new一个java.sql.Timestamp
if (value instanceof java.util.Date) {
return new java.sql.Timestamp(((java.util.Date) value).getTime());
}
long longValue = 0;
// fastjson支持数字格式转换为Timestamp,(不加注解的话用java bean转json时默认也是将Timestamp转为:Number)
if (value instanceof Number) {
longValue = ((Number) value).longValue();
}
//如果是字符串,判断非空非null
if (value instanceof String) {
String strVal = (String) value;
if (strVal.length() == 0 //
|| "null".equals(strVal) //
|| "NULL".equals(strVal)) {
return null;
}
//直接将字符串转换为Long类型(这里可以看出fastjson只支持
//数字的字符串类型,不支持Date,Calendar等的字符串类型)
//例如 "1571637921000"可以,而"2019-10-21 14:05:21"则跑出转换异常 :For input string:
longValue = Long.parseLong(strVal);
}
if (longValue <= 0) {
throw new JSONException("can not cast to Date, value : " + value);
}
return new java.sql.Timestamp(longValue);
}
另外,java实体类中的注解
@JSONField(format="yyyy-MM-dd HH:mm:ss")作用是规定fastjson转换为java bean对象时的格式
加上注解,打印报文为:
对象转json:{"addUsername":"张飞","addtime":"2019-10-21 14:05:21","editUsername":"赵云","edittime":"2019-09-21 14:05:22"} 格式良好,
不加,则报文为:对象转json:{"addUsername":"张飞","addtime":1571637921000,"editUsername":"赵云","edittime":1569045922000}
可以看出,不加的话java.sql.Timestamp格式和java.util.Date格式的字段都被转换成了数字类型!
上一篇: 一位软件工程师的6年总结收藏
下一篇: 浅谈Javascript中函数的继承模式