当 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
}
由于 Tickets 实体是由 CRON 脚本自动生成或在日期范围内指定的,其中 Ticket 具有每周的星期一和星期日:
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
最佳答案
时区问题
一样多
事实证明,Spring 从数据库中检索日期,我猜它使用 java.util.Date
(考虑系统时区)首先解析它,然后将其转换为 java.time.LocalDate
,使用TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
完全解决问题,像这样使用它:
@SpringBootApplication
public class MyTicketApplication {
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SpringApplication.run(MyTicketApplication.class, args);
}
}
关于java - jackson 本地日期 : one day off during serialization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53715653/