为什么它们有时不一致?从服务器
java.sql.Date
接收的 Postman
类型的值然后由 com.google.gson.Gson
反序列化(在实例化 Gson 实例之前,我注册了两个适配器 - 一个用于反序列化 java.sql.Date
,另一个用于反序列化 java.sql.Time
。)。以及从服务器发送的 json 字符串。
我尝试从
Postman
发送请求到Tomcat v9.0
,并将原始数据(这里是一个json字符串)反序列化到DietDiary
对象,该对象包含两个类型为java.sql.Date
和java.sql.Time
的字段,使用com.google.gson
包.
Postman
中请求原始数据的两个键。
"createDate":"2022-05-05",
"createTime":"12:00:00",
但是 Eclipse 中的控制台会打印
Ready to deserialize.
dietDiary:DietDiary [diaryId=2, userId=2, createDate=2021-12-26, createTime=00:00:00, totalFat=2.52, totalCarbon=2.3, totalProtein=2.1, totalFiber=2.1, totalSugar=1.2, totalSodium=1.1, totalCalories=1.21]
不知道为什么?
任何有关此问题的回复都将受到高度赞赏。
这里有详细信息。
Postman
GET
http://localhost:8080/HealthHelper/dietDiary/test
一个 json 字符串。
{
"diaryId":2,
"userId":2,
"createDate":"2022-05-05",
"createTime":"12:00:00",
"totalFat":2.52,
"totalCarbon":2.3,
"totalProtein":2.1,
"totalFiber":2.1,
"totalSugar":1.2,
"totalSodium":1.1,
"totalCalories":1.21
}
Tomcat
v9.0(版本9)
/HealthHelper/src/main/java/controller/TestController.java
package controller;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.sql.Date;
import java.sql.Time;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import constant.SqlDatePattern;
import constant.SqlTimePattern;
import util.gson.GsonForSqlDateAndSqlTime;
import util.gson.deserializer.JsonDeserializerForSqTime;
import util.gson.deserializer.JsonDeserializerForSqlDate;
import vo.DietDiary;
@WebServlet("/dietDiary/test")
public class TestController extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
Gson gson = GsonForSqlDateAndSqlTime.gson;
DietDiary dietDiary = gson.fromJson(req.getReader(), DietDiary.class);
System.out.println("Ready to deserialize.");
System.out.println("dietDiary:"+dietDiary);
}
}
/HealthHelper/src/main/java/vo/DietDiary.java
满足JavaBean规则且不被污染的类。
package vo;
import java.sql.Date;
import java.sql.Time;
public class DietDiary {
private int diaryId;
private int userId;
private Date createDate;
private Time createTime;
private Double totalFat;
private Double totalCarbon;
private Double totalProtein;
private Double totalFiber;
private Double totalSugar;
private Double totalSodium;
private Double totalCalories;
public int getDiaryId() {
return diaryId;
}
public void setDiaryId(int diaryId) {
this.diaryId = diaryId;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Time getCreateTime() {
return createTime;
}
public void setCreateTime(Time createTime) {
this.createTime = createTime;
}
public Double getTotalFat() {
return totalFat;
}
public void setTotalFat(Double totalFat) {
this.totalFat = totalFat;
}
public Double getTotalCarbon() {
return totalCarbon;
}
public void setTotalCarbon(Double totalCarbon) {
this.totalCarbon = totalCarbon;
}
public Double getTotalProtein() {
return totalProtein;
}
public void setTotalProtein(Double totalProtein) {
this.totalProtein = totalProtein;
}
public Double getTotalFiber() {
return totalFiber;
}
public void setTotalFiber(Double totalFiber) {
this.totalFiber = totalFiber;
}
public Double getTotalSugar() {
return totalSugar;
}
public void setTotalSugar(Double totalSugar) {
this.totalSugar = totalSugar;
}
public Double getTotalSodium() {
return totalSodium;
}
public void setTotalSodium(Double totalSodium) {
this.totalSodium = totalSodium;
}
public Double getTotalCalories() {
return totalCalories;
}
public void setTotalCalories(Double totalCalories) {
this.totalCalories = totalCalories;
}
public boolean equals(Object object) {
if(object instanceof DietDiary) {
return false;
}
DietDiary dietDiary = (DietDiary) object;
if(!(this.getDiaryId() == dietDiary.getDiaryId())) {
return false;
}
if(!(this.getUserId() == dietDiary.getUserId())) {
return false;
}
if(!(this.getCreateDate() == dietDiary.getCreateDate())) {
return false;
}
if(!(this.getCreateTime() == dietDiary.getCreateTime())) {
return false;
}
return true;
}
@Override
public String toString() {
return "DietDiary [diaryId=" + diaryId + ", userId=" + userId + ", createDate=" + createDate + ", createTime="
+ createTime + ", totalFat=" + totalFat + ", totalCarbon=" + totalCarbon + ", totalProtein="
+ totalProtein + ", totalFiber=" + totalFiber + ", totalSugar=" + totalSugar + ", totalSodium="
+ totalSodium + ", totalCalories=" + totalCalories + "]";
}
}
/HealthHelper/src/main/java/util/gson/GsonForSqlDateAndSqlTime.java
我在
java.sql.Date
公共类中放置了一个 gson 实例,其适配器已注册用于反序列化 java.sql.Time
和 GsonForSqlDateAndSqlTime
package util.gson;
import java.sql.Date;
import java.sql.Time;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import util.gson.deserializer.JsonDeserializerForSqTime;
import util.gson.deserializer.JsonDeserializerForSqlDate;
public class GsonForSqlDateAndSqlTime {
public static Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, JsonDeserializerForSqlDate.dateDeserializer)
.registerTypeAdapter(Time.class, JsonDeserializerForSqTime.timeDeserializer)
.create();
}
/HealthHelper/src/main/java/util/gson/deserializer/JsonDeserializerForSqlDate.java
package util.gson.deserializer;
import java.lang.reflect.Type;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import constant.SqlDatePattern;
public class JsonDeserializerForSqlDate {
public static JsonDeserializer<Date> dateDeserializer = new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat(SqlDatePattern.sqlDatePattern);
try {
return new Date(dateFormat.parse(json.getAsString()).getTime());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
};
}
/HealthHelper/src/main/java/util/gson/deserializer/JsonDeserializerForSqTime.java
package util.gson.deserializer;
import java.lang.reflect.Type;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import constant.SqlTimePattern;
public class JsonDeserializerForSqTime {
public static JsonDeserializer<Time> timeDeserializer = new JsonDeserializer<Time>() {
@Override
public Time deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
SimpleDateFormat timeFormat = new SimpleDateFormat(SqlTimePattern.sqlTimePattern);
try {
return new Time(timeFormat.parse(json.getAsString()).getTime());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
};
}
我已阅读这些文档。
我知道为什么!!!
原因似乎很明显。
我滥用该标志来创建
java.text.SimpleDateFormat
实例(发生在 /HealthHelper/src/main/java/util/gson/deserializer/JsonDeserializerForSqlDate.java
中),因此 java.sql.Date
解析是错误的。
在此声明中
SimpleDateFormat dateFormat = new SimpleDateFormat(SqlDatePattern.sqlDatePattern);
静态字段
SqlDatePattern.sqlDatePattern
被分配给 yyyy-MM-DD
。
我把它改为
yyyy-MM-dd
。
我还将
SqlTimePattern.sqlTimePattern
从hh:mm:ss
更改为HH:mm:ss
在以下声明中。
SimpleDateFormat timeFormat = new SimpleDateFormat(SqlTimePattern.sqlTimePattern);
然后我再次测试,得到了预期的结果。
在 Eclipse 的控制台中,它打印
Ready to deserialize.
dietDiary:DietDiary [diaryId=2, userId=2, createDate=2022-05-05, createTime=12:00:00, totalFat=2.52, totalCarbon=2.3, totalProtein=2.1, totalFiber=2.1, totalSugar=1.2, totalSodium=1.1, totalCalories=1.21]