当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脚本自动生成或在日期范围内指定的,因此,票证具有每周的星期一和星期日:
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 useJDBCCompliantTimezoneShift=false&useLegacyDatetimeCode=false&serverTimezone=UTC
中指定了spring.datasource.url
答案 0 :(得分:0)
尽可能多
事实证明,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);
}
}