Reputation: 71
Is there a way to custom validate 2 of request parameters coming into endpoint in Spring? I would like to be able to validate them with my custom function. Something like add annotation to the request params or on the function where these params are and force these params to be validated by another custom written function.
I need to take both params at the same time, because the validation output of one is dependent on the value of the other one.
I have searched and found some solutions with custom constraint annotations but from what I've read it doesn't seem to solve my problem.
Upvotes: 1
Views: 2544
Reputation: 21
As rightly mentioned, using valiktor is the best option. I have used it in our product as well and it works like a charm.
Below is a snippet example as how you are use it to compare two properties of the same class.
fun isValid(myObj: Myobj): Boolean {
validate(myObj) {
validate(MyObj::prop1).isGreaterThanOrEqualTo(myobj.prop2)
}
Valiktor throws exception with proper message if the validation fails. It also enables you to create custom exception messages if you want to.
Now all you need to do is, create a class for your requestBody and check your conditions with isValid() method explicitly or move it into init block and do it implicitly.
Valiktor has a large number of validations as compared to JSR380, where creating custom validation is a little messy as compared to Valiktor.
Upvotes: 2
Reputation: 2378
If you're going to use the request params to create a POJO, then you can simply use the Javax Validation API
.
public class User {
private static final long serialVersionUID = 1167460040423268808L;
@NotBlank(message = "ID cannot be to empty/null")
private int id;
@NotBlank(message = "Group ID cannot be to empty/null")
private String role;
@NotBlank(message = "Email cannot be to empty/null")
private String email;
@NotNull(message = "Password cannot be to null")
private String password;
}
To validate -
@PostMapping("/new")
public String save(@ModelAttribute @Validated User user, BindingResult bindingResult, ModelMap modelMap) throws UnknownHostException {
if (!bindingResult.hasErrors()) {
// Proceed with business logic
} else {
Set<ConstraintViolation<User>> violations = validator.validate(user);
List<String> messages = new ArrayList<>();
if (!violations.isEmpty()) {
violations.stream().forEach(staffConstraintViolation -> messages.add(staffConstraintViolation.getMessageTemplate()));
modelMap.addAttribute("errors", messages);
Collections.sort(messages);
}
return "new~user";
}
}
Upvotes: 1
Reputation: 516
valiktor is really good library to validate.
You can do somenthing like:
data class ValidatorClass(val field1: Int, val field2: Int) {
init {
validate(this) {
validate(ValidatorClass::field1).isPositive()
validate(ValidatorClass::field2).isGreaterThan(field1)
}
}
}
make request parameter not required:
@RequestMapping(path = ["/path"])
fun fooEndPoint(@RequestParam("field1", required = false) field1: Int,
@RequestParam("field2", required = false) field2: Int) {
ValidatorClass(field1, field2) //it will throw an exception if validation fail
}
You can handle exception using try-catch
or using and ExceptionHandler
defined by valiktor.
Using valiktor you can validate fields depending on other fields. You can create one kotlin file where you write all classes that you use to validate fields from requests and in the same way you can use valiktor in you @RequestBody
models to validate it.
Upvotes: 0
Reputation: 337
You can write custom validator by using Validator Check :: https://docs.spring.io/spring-framework/docs/3.0.0.RC3/reference/html/ch05s02.html Example :: https://www.baeldung.com/spring-data-rest-validators
Upvotes: 0