前后端统一日期传输方式(org.codehaus.jackson.map.JsonMappingException)

前后端统一日期传输方式

背景(问题)

spring 工程编写代码时,遇到两个问题。

  1. 后端传输到前端时,要求把时间戳转换成字符串。即123456789 转换成 yyyy-MM-dd HH:mm:ss
  2. 前端传输到后端时,要求把字符串转换成时间戳(Date)。即 yyyy-MM-dd HH:mm:ss 转换成 123456789(Date)

后端到前端

数据库字段为 Date 或 TIMESTAMP , JAVA 类型为 Date,此时 Date 表现为 时间戳。要求把时间戳转换成字符串

  1. 转换类代码如下:
package org.jeecgframework.core.spring.convert;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

/**
 * @author wsl
 */
public class JsonDateTypeConvert extends JsonSerializer<Date> {
    @Override
    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
        throws IOException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = simpleDateFormat.format(date);
        jsonGenerator.writeString(dateStr);
    }

}

  1. 应用到对应的 POJO 上,代码如下 :

get方法上配置注解 @JsonSerialize(using = JsonDateTypeConvert.class)

package org.jeecgframework.core.common.entity;

import java.util.Date;
import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.jeecgframework.core.spring.convert.CustomJsonDateDeserializer;
import org.jeecgframework.core.spring.convert.JsonDateTypeConvert;

import com.alibaba.fastjson.annotation.JSONField;

@MappedSuperclass
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "pkEmpty"})
public abstract class IdAndTimeEntity extends IdEntity {

    @JSONField(format = "yyyy-MM-dd HH:mm")
    private Date createTime;

    private String createdId;

    private Date lastOperateTime;

    private String lastOperatedId;

    @Column(name = "create_time")
    @JsonSerialize(using = JsonDateTypeConvert.class)
    public Date getCreateTime() {
        return createTime;
    }

    @JsonDeserialize(using = CustomJsonDateDeserializer.class)
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Column(name = "created_id")
    public String getCreatedId() {
        return createdId;
    }

    public void setCreatedId(String createdId) {
        this.createdId = createdId;
    }

    @Column(name = "last_operate_time")
    @JsonSerialize(using = JsonDateTypeConvert.class)
    public Date getLastOperateTime() {
        return lastOperateTime;
    }

    @JsonDeserialize(using = CustomJsonDateDeserializer.class)
    public void setLastOperateTime(Date lastOperateTime) {
        this.lastOperateTime = lastOperateTime;
    }

    @Column(name = "last_operated_id")
    public String getLastOperatedId() {
        return lastOperatedId;
    }

    public void setLastOperatedId(String lastOperatedId) {
        this.lastOperatedId = lastOperatedId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }

    @Transient
    private boolean isPkEmpty() {
        Object pk = getId();
        if (pk == null) {
            return true;
        }
        if (pk instanceof String) {
            return StringUtils.isEmpty(pk.toString());
        }
        return false;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }

        IdAndTimeEntity other = (IdAndTimeEntity)obj;
        if (other.isPkEmpty()) {
            return false;
        }

        return Objects.equals(getId(), other.getId());
    }
}

前端到后端

前端为 yyyy-MM-dd HH:mm:ss 。后端 JAVA 接收包装类型为 Date ,会报错

org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance
  1. 转换类代码如下
package org.jeecgframework.core.spring.convert;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.springframework.util.StringUtils;

/**
 * @author wansiliang
 * @date 2019/12/4 11:17
 */
public class CustomJsonDateDeserializer extends JsonDeserializer<Date> {
    private SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String text = jp.getText();

        if (StringUtils.hasText(text)) {
            try {
                if (text.indexOf(":") == -1 && text.length() == 10) {
                    return this.dateFormat.parse(text);
                } else if (text.indexOf(":") > 0 && text.length() == 19) {
                    return this.datetimeFormat.parse(text);
                } else {
                    throw new IllegalArgumentException("Could not parse date, date format is error ");
                }
            } catch (ParseException ex) {
                IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
                iae.initCause(ex);
                throw iae;
            }
        } else {
            return null;
        }
    }

}

  1. 应用到 POJO 上代码如下:

set方法上使用注解@JsonDeserialize(using = CustomJsonDateDeserializer.class)
对应属性上使用注解 @JSONField(format = “yyyy-MM-dd HH:mm”)

package org.jeecgframework.core.common.entity;

import java.util.Date;
import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.jeecgframework.core.spring.convert.CustomJsonDateDeserializer;
import org.jeecgframework.core.spring.convert.JsonDateTypeConvert;

import com.alibaba.fastjson.annotation.JSONField;

@MappedSuperclass
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "pkEmpty"})
public abstract class IdAndTimeEntity extends IdEntity {

    @JSONField(format = "yyyy-MM-dd HH:mm")
    private Date createTime;

    private String createdId;

    private Date lastOperateTime;

    private String lastOperatedId;

    @Column(name = "create_time")
    @JsonSerialize(using = JsonDateTypeConvert.class)
    public Date getCreateTime() {
        return createTime;
    }

    @JsonDeserialize(using = CustomJsonDateDeserializer.class)
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Column(name = "created_id")
    public String getCreatedId() {
        return createdId;
    }

    public void setCreatedId(String createdId) {
        this.createdId = createdId;
    }

    @Column(name = "last_operate_time")
    @JsonSerialize(using = JsonDateTypeConvert.class)
    public Date getLastOperateTime() {
        return lastOperateTime;
    }

    @JsonDeserialize(using = CustomJsonDateDeserializer.class)
    public void setLastOperateTime(Date lastOperateTime) {
        this.lastOperateTime = lastOperateTime;
    }

    @Column(name = "last_operated_id")
    public String getLastOperatedId() {
        return lastOperatedId;
    }

    public void setLastOperatedId(String lastOperatedId) {
        this.lastOperatedId = lastOperatedId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }

    @Transient
    private boolean isPkEmpty() {
        Object pk = getId();
        if (pk == null) {
            return true;
        }
        if (pk instanceof String) {
            return StringUtils.isEmpty(pk.toString());
        }
        return false;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }

        IdAndTimeEntity other = (IdAndTimeEntity)obj;
        if (other.isPkEmpty()) {
            return false;
        }

        return Objects.equals(getId(), other.getId());
    }
}

发布了30 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wsl9420/article/details/103147802