在基于 spring-boot 的项目中,我有一个简单的 DTO 对象:
public class ExpenseDTO {
@Min(value = 1, message = "expense.amount.negative")
private int amount;
@Past
private Calendar createdAt;
// setters/getters/constructor are omitted
}
还有这样的休息 Controller :
public class ExpenseController {
private final ExpenseService expenseService;
@Autowired
public ExpenseController(ExpenseService expenseService) {
this.expenseService = expenseService;
}
@RequestMapping(value = ADD_EXPENSE, method = POST)
public ResponseEntity addExpense(@Valid @RequestBody ExpenseDTO expenseDTO, Principal principal) {
expenseService.addExpense(expenseDTO, principal.getName());
return ResponseEntity.ok().build();
}
}
从客户端我要发送一个当前日期:{“createdAt”:“2017-01-27T21:32:19.183Z”}但在后端验证期间,日期将被解析为“2017-01” -28T01:30:00.000+0200"所以结果是错误的并且验证失败。我尝试使用 @JsonFormat 但没有结果。
注意:我正在使用 H2 db,如果从 DTO 对象中删除 @Past,一切都会正常工作,但我必须禁用 future 日期。
那么我如何在没有时区的情况下验证日期,我的意思是我需要后端的日期与从客户端发送的日期完全相同?!
最佳答案
可能是因为TimeZone
在您的本地机器中设置。您可以将其设置为UTC
在应用程序启动时,例如:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
此外,您还需要设置 TimeZone
在 SimpleDateFormat
正在配置的实例 ObjectMapper
(如果您将 ObjectMapper
配置为 bean),例如:
@Bean
public ObjectMapper objectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setSerializationInclusion(Include.NON_NULL);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
objectMapper.setDateFormat(simpleDateFormat);
return objectMapper;
}
如果仍然不起作用,我建议为日历创建一个自定义反序列化器并手动设置 TimeZone
在新实例中,例如:
@Component
public class CalendarDeserialiser extends JsonDeserializer<Calendar>{
TimeZone UTC = TimeZone.getTimeZone("UTC");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");
@Override
public Calendar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Calendar calendar;
try{
calendar = Calendar.getInstance(UTC);
calendar.setTime(dateFormat.parse(p.getText()));
}catch(Exception e){
throw new IOException(e);
}
calendar.setTimeInMillis(p.getLongValue());
return calendar;
}
}
并注释你的 Calendar
字段 @JsonDeserialize(using = CalendarDeserialiser.class)
.
关于java - JPA @过去日期/日历验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41903530/