I'm stuck in an apparently simple problem: I want to perform some custom validation based on the object id in a PUT request.
@RequestMapping(value="/{id}", method=RequestMethod.PUT)
public ResponseEntity<Void> update(@Valid @RequestBody ClientDTO objDto, @PathVariable Integer id) {
Client obj = service.fromDTO(objDto);
service.update(obj);
return ResponseEntity.noContent().build();
}
I'd like to create a custom validator to output a custom message in case I update some field that can't be the same of another object in my database. Something like this:
public class ClientUpdateValidator implements ConstraintValidator<ClientUpdate, ClientDTO> {
@Autowired
private ClientRepository repo;
@Override
public void initialize(ClientInsert ann) {
}
@Override
public boolean isValid(ClientDTO objDto, ConstraintValidatorContext context) {
Client aux = repo.findByName(objDto.getName());
if (aux != null && !aux.getId().equals(objDto.getId())) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("Already exists")
.addPropertyNode("name").addConstraintViolation();
return false;
}
return true;
}
}
However, the object id comes from @PathVariable, not from @RequestBody. I can't call "objDto.getId()" like I did above.
On the other hand, it doesn't make much sense to obligate to fill up the object id in the request body, because this way the path variable would become meaninless.
How can I solve this problem? Is there a way to inject the id from PathVariable into RequestBody object before bean validation is executed? If not, what would be a viable solution? Thanks.
Try to inject httpServletRequest into the custom validator
public class ClientUpdateValidator implements ConstraintValidator<ClientUpdate, ClientDTO> {
@Autowired
private HttpServletRequest request;
@Autowired
private ClientRepository repo;
@Override
public void initialize(ClientInsert ann) {
}
@Override
public boolean isValid(ClientDTO objDto, ConstraintValidatorContext context) {
// for example your path to put endpoint is /client/{id}
Map map = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
String id = map.get("id");
Client aux = repo.findByName(objDto.getName());
if (aux != null && !aux.getId().equals(id)) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("Already exists")
.addPropertyNode("name").addConstraintViolation();
return false;
}
return true;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With