【问题标题】:Validation of Date in the past过去日期的验证
【发布时间】:2021-07-14 09:07:53
【问题描述】:

我需要验证生日是过去的。

我有以下表格:

@Data
public class PersonForm {
    static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
    private Long id;
    @NotNull(message = "Name should not be null")
    private String name;
    @NotNull(message = "Date should not be null")
    @Pattern(regexp = "^(0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.]((19|2[0-9])[0-9]{2})$", message = "Date format: dd.mm.yyyy")
    private String date;
    @Valid
    private List<CarForm> carForms;

如您所见,在这里我验证日期字符串的格式是否正确。 我有以下实体:

@Data
@Entity
@Table(name = "person")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    private String name;
    @Past(message = "Birthdate should be in the past")
    private Date birthdate;
    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "persons_cars",
    joinColumns = @JoinColumn(name = "person_id"),
    inverseJoinColumns = @JoinColumn(name = "car_id"))
    private List<Car> cars;
}

以及一种将一个转换为另一个的实用方法:

public class PersonFormConverter {
    static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
    public static Person toPerson(PersonForm personForm) throws ParseException {
        Person person = new Person();
        person.setId(personForm.getId());
        person.setName(personForm.getName());
        person.setBirthdate(simpleDateFormat.parse(personForm.getDate()));
        if(personForm.getCarForms()!=null){
            person.setCars(personForm.getCarForms().stream().map(CarFormConverter::toCar).collect(Collectors.toList()));
        }
        return person;
    }

正如您在我的实体类 Person 中看到的,我对字段 Date 有一个验证约束,但它在我的控制器中无法正常工作:

@PostMapping("/person")
public ResponseEntity<Object> createNew(@RequestBody @Valid PersonForm personForm, BindingResult bindingResult) throws ParseException {
    if(bindingResult.hasErrors()){
        return new ResponseEntity<>(bindingResult.getFieldError().getDefaultMessage(), HttpStatus.BAD_REQUEST);
    }
    return new ResponseEntity<>(personService.createNewPerson(PersonFormConverter.toPerson(personForm)), HttpStatus.OK);
}

如果输入的日期是过去的,服务器会返回错误代码 500,而不是 400。我可以理解为什么会发生这种情况,但我无法找出正确的方法来验证我的日期是否是过去的。你能告诉我正确的变种是什么吗?我相信这一定是一个简单的解决方案,而且我很可能走错了方向。

编辑: 在这里,我从我的 Service 类中添加了我的创建方法:

public Person createNewPerson(@Valid Person person) {
    return personRepository.save(person);
}

不幸的是,这里的注释没有帮助

【问题讨论】:

  • 对实体的验证应该发生在对personService.createNewPerson(PersonFormConverter.toPerson(personForm)) 的调用中,如果验证失败,您可能会收到异常。因此,您需要捕获该异常。
  • 我编辑了我的帖子。你说的是这个吗?
  • 基本上是的。尝试在控制器中使用 try-catch 块来捕获存储库抛出的验证异常(以及您的服务)。
  • 成功了。如果您添加答案,我会接受。谢谢!

标签: java validation


【解决方案1】:

你的问题在这里:

return new ResponseEntity<>(personService.createNewPerson(PersonFormConverter.toPerson(personForm)), HttpStatus.OK);

此行调用服务,该服务又调用存储库并执行验证并在数据无效时引发异常。该异常会冒泡到您的控制器,并且由于您没有捕获它,因此 Spring 框架会这样做并返回状态 500。那是因为它不知道异常的含义,所以它只返回一个“服务器错误”。

要改为返回 400,您需要将该调用包装在 try-catch 中:

try {
  return new ResponseEntity<>(personService.createNewPerson(PersonFormConverter.toPerson(personForm)), HttpStatus.OK);
} catch (TheValidationException e) { //don't rememer the exact name of the exception atm
  //if you can, extract information on what is invalid and tell the caller
  return new ResponseEntity<>("Invalid data provided", HttpStatus.BAD_REQUEST);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-15
    • 2011-08-05
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 2021-04-14
    相关资源
    最近更新 更多