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格式的字段都被转换成了数字类型!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值