背景(问题)
spring 工程编写代码时,遇到两个问题。
- 后端传输到前端时,要求把时间戳转换成字符串。即123456789 转换成 yyyy-MM-dd HH:mm:ss
- 前端传输到后端时,要求把字符串转换成时间戳(Date)。即 yyyy-MM-dd HH:mm:ss 转换成 123456789(Date)
后端到前端
数据库字段为 Date 或 TIMESTAMP , JAVA 类型为 Date,此时 Date 表现为 时间戳。要求把时间戳转换成字符串。
- 转换类代码如下:
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);
}
}
- 应用到对应的 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
- 转换类代码如下
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;
}
}
}
- 应用到 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());
}
}