java - JPA @过去日期/日历验证

标签 java hibernate date jpa jackson

在基于 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"));

此外,您还需要设置 TimeZoneSimpleDateFormat正在配置的实例 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/

相关文章:

java - 如何为一组方法编写单元测试,其中每个方法都依赖于其他方法?

java - Spring WebClient - HTTP 错误状态的自定义响应回调

java - 缓存整个表

java - 查找上个月的最后一个星期五并检查当前日期之间有多少天

Linux 日期格式 hh-mm-ss

r - 在R中绘制每月天气数据

java - 机器人 : how to create new Directory in my package path

java - ArrayList<SuperClass> 中的子类对象是否保留子类特有的方法?

java - 有没有办法让 Play 框架和 JPA 在列名中使用下划线?

java - Hibernate,无法执行查询,SQL 错误 : 17059, SQLState:99999