gpt4 book ai didi

java - 当存在 JsonSerializer() 时,JsonSerializer() 不适用于 java.util.Date 字段

转载 作者:行者123 更新时间:2023-11-30 05:23:55 26 4
gpt4 key购买 nike

在我的java应用程序中,我分别使用 JsonSerializer 和 JsonSerializer() 来序列化 java.util.Date 和 java.sql.Timestamp 字段。但问题是,当我使用 gson 将对象解析为 json 字符串时,java.util.Date 和 java.sql.Timestamp 字段都被序列化。 util.Date 字段使用 JsonSerializer() 序列化器而不是 JsonSerializer。下面是我的代码。

Gson gson;
GsonBuilder builder;
SimpleDateFormat dtf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat dtfDate=new SimpleDateFormat("yyyy-MM-dd");
builder = new GsonBuilder();

builder.registerTypeAdapter(Timestamp.class, new JsonSerializer<Timestamp>() {
@Override
public JsonElement serialize(Timestamp src, Type typeOfSrc, JsonSerializationContext context) {
dtf.setTimeZone(TimeZone.getTimeZone("UTC"));
String jsDate = dtf.format(src);
System.out.println("Timestamp : src - "+src+" jsDate - "+jsDate+" typeOfSrc - "+typeOfSrc);
return new JsonPrimitive(jsDate);
}
});
builder.registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
@Override
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
String jsDate = dtfDate.format(src);
System.out.println("Date : src - "+src+" jsDate - "+jsDate+" typeOfSrc - "+typeOfSrc);
return new JsonPrimitive(jsDate);
}
});
gson = builder.create();
PersonSubstitution personSubstitution = loopDao.getPersonSubstitution(Integer.parseInt(deptId),date);
String jsonAccts = gson.toJson(personSubstitution, PersonSubstitution.class);

PersonSubstitution.class:

import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Objects;


@Entity
@Table(name = "person_substitution")
public class PersonSubstitution implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;

@JoinColumn(name = "dept_id", referencedColumnName = "id", nullable = false)
@ManyToOne(optional = false)
private Departments deptId;

@Column(name = "date")
private Date date;

@JoinColumn(name = "staff_id", referencedColumnName = "person_id", nullable = false)
@OneToOne(optional = false)
private Person staffId;

@Column(name = "created_on")
private Timestamp createdOn;

public PersonSubstitution() {

}

public PersonSubstitution(int id, Departments deptId, Date date, Person staffId, Timestamp createdOn) {
this.id = id;
this.deptId = deptId;
this.date = date;
this.staffId = staffId;
this.createdOn = createdOn;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Departments getDeptId() {
return deptId;
}

public void setDeptId(Departments deptId) {
this.deptId = deptId;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}

public Person getStaffId() {
return staffId;
}

public void setStaffId(Person staffId) {
this.staffId = staffId;
}

public Timestamp getCreatedOn() {
return createdOn;
}

public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
}

我输入System.out.println()在两个序列化器中,只有 Timestamp Stement 的工作方式如下:

Timestamp : src - 2019-11-28 00:00:00.0 jsDate - 2019-11-27 18:30:00 typeOfSrc - class java.sql.Timestamp
Timestamp : src - 2019-11-25 12:08:14.0 jsDate - 2019-11-25 06:38:14 typeOfSrc - class java.sql.Timestamp

那么日期字段有没有办法使用builder.registerTypeAdapter(Date.class, new JsonSerializer<Date>() {...}而不是builder.registerTypeAdapter(Date.class, new JsonSerializer<Timestamp>() {...} ??

最佳答案

它的工作原理是这样的,因为在运行时datecreatedOnTimestamp。您需要将给定的序列化器分配给一个字段。因此,您需要创建一个自定义序列化程序:

class DateJsonSerializer implements JsonSerializer<Date> {

private final ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

@Override
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
String formatted = formatter.get().format(src);

return new JsonPrimitive(formatted);
}
}

时间戳序列化器:

class TimestampJsonSerializer implements JsonSerializer<Timestamp> {

private final ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat;
});

@Override
public JsonElement serialize(Timestamp src, Type typeOfSrc, JsonSerializationContext context) {
String formatted = formatter.get().format(src);
return new JsonPrimitive(formatted);
}
}

并为 Date 字段声明它:

@JsonAdapter(DateJsonSerializer.class)
private Date date;

您仍然可以将其注册为 Date 类的全局序列化器:

Gson gson = new GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(Timestamp.class, new TimestampJsonSerializer())
.registerTypeAdapter(Date.class, new DateJsonSerializer())
.create();

注意:我使用了ThreadLocal,因为SimpleDateFormat不是线程安全的。

关于java - 当存在 JsonSerializer<Timestamp>() 时,JsonSerializer<Date>() 不适用于 java.util.Date 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59027234/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com