【发布时间】:2019-05-11 22:37:18
【问题描述】:
当 Jackson 尝试从我的课程中序列化 LocalDate 列但数据库完全正常时,我遇到了问题,每次 JSON 从数据库中显示一天。
当数据库按预期显示时:
2018-10-01
调用 Spring REST 入口点的 JSON 输出:
{ "ticketStart": "2018-09-30" }
这表明一天已经过去了。数据库表不存储时间,只存储预期的日期,时区是完全可以丢弃的,因为我的项目是供内部使用的。我尝试用谷歌搜索我的具体问题,发现唯一的问题是 this 和 this,但没有一个能解决我的问题。
有一种方法可以强制从我的数据库中按原样序列化日期(又名:禁用转换)。
实体代码:
@Entity
@Table(name="tickets")
public class Ticket
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Getter
@Setter
private long TicketId;
@Column(unique=true)
@Getter
@Setter
private LocalDate TicketStart;
@Column(unique=true)
@Getter
@Setter
private LocalDate TicketEnd;
//.... some fields omitted
}
由于门票实体由 CRON 脚本自动生成或在日期范围内指定,其中门票具有每周的星期一和星期日:
public Ticket GenerateEmptyTicket(LocalDate begin, LocalDate end)
{
Ticket newTicket = new Ticket();
newTicket.setTicketStart(begin);
newTicket.setTicketEnd(end);
newTicket.setYear(begin.getYear());
newTicket.setMonth(begin.getMonth());
newTicket.setLastMod(new Date());
boolean isLocked = false;
LocalDate date = LocalDate.now();
if(date.isAfter(end)) isLocked = true;
newTicket.setLocked(isLocked);
//@TODO: Set a default responsible in the configuration.
SystemUser rootUser = usersRepo.findByUsername("root").get();
newTicket.setResponsable(rootUser);
return newTicket;
}
public void GenerateTicketsBetweenTwoDates(LocalDate begin, LocalDate end)
{
List<LocalDate> weekDates = new ArrayList<>();
if(begin.getDayOfWeek() != DayOfWeek.MONDAY)
while(begin.getDayOfWeek() != DayOfWeek.MONDAY)
begin = begin.minusDays(1);
LocalDate tmp = begin;
while(tmp.isBefore(end)){
weekDates.add(tmp);
tmp = tmp.plusWeeks(1);
}
if(end.getDayOfWeek() == DayOfWeek.MONDAY)
weekDates.add(end);
LocalDate current = LocalDate.now();
List<Ticket> ticketsToSave = new ArrayList<>();
for(LocalDate dat : weekDates)
{
logger.info("BEGIN DATE:" + dat.toString());
LocalDate __end = dat.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
if(current.isAfter(__end)) logger.info("LOCKED: YES");
ticketsToSave.add(GenerateEmptyTicket(dat, __end));
}
ticketsRepo.saveAll(ticketsToSave);
}
数据库和 Jackson 序列化没有显示任何错误,只是序列化产生了不希望的“休息日”结果。
注意:数据库 JDBC 连接 (MySQL) 从 application.properties spring.datasource.url 指定 useJDBCCompliantTimezoneShift=false&useLegacyDatetimeCode=false&serverTimezone=UTC
【问题讨论】:
-
请附上您使用的代码。您是否已经使用调试器来确定是在从数据库中读取日期时引入错误,还是在将日期序列化为 JSON 时引入错误?
-
@Joni 数据库中没有引入错误,正如我之前提到的,从 Java 添加到数据库的日期显示了预期的值,但是一旦从 JSON 结果显示显示一次隐式转换我做了一个 GET 调用,Spring 没有在日志/调试输出中显示任何内容。
-
如果在反序列化之前调试对象会得到什么?
-
多么有趣的事情,我只是这样做并用 Java 从数据库中检索对象,它显示了休息日的副作用转换
-
您能否在您的 LodalDate 字段之上添加:@JsonDeserialize(using = LocalDateDeserializer.class) @JsonSerialize(using = LocalDateSerializer.class) 并重试是否可行!
标签: java spring date spring-boot jackson