Reputation: 197
I am wondering what is the best way to build messages in controller based on a service result, to the front end. I am thinking in java/spring context using rest controllers, but it reflects the MVC model as well. Obviously the examples I have seen on the internet are way to simple to understand what are best practices in real world application. So, to the case, let's assume a following scenario:
So now the questions:
As a result of controller method execution, I would retuun a Map of objects, that will be parsed into JSON. Possible entities would be:
{ "result":"12" }
{ "errorCode":"incorrect parameters" }
is this correct, or should I aim into different error handling? I know that I could additionally use a http error codes for example 400, or 406 to indicate that input parameters are incorrect, but personally I prefer not to use http error codes to indicate application logic result. (I consider input validation as appliaciton logic)
a) is a < b and then inform user with a message "a cannot be smaller than b"
b) is a*a == b and then inform user with a message "a squared cannot be equal to b".
How should I provide the additional message based on the result? I can think of two solutions:
return boolean value indicating validation result, and additionally use exceptions for negative result. (bonus question, in such scenario should the exception be checked or unchecked?)
Upvotes: 0
Views: 1575
Reputation: 2370
Spring supports custom validation. There is an annotation @Valid
. You can add it before your parameter in Controller. I'll show it on the example. Firstly, create class with implements Validator interface:
@Component
public class MathValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return MatchRequest.class.equals(aClass);
}
@Override
public void validate(Object o, Errors errors) {
MatchRequest request = (MatchRequest) o;
if (request.getValue() == null) {
errors.rejectValue("value", "Value cannot be empty");
}
//add another validation logic here.
}
}
Then, in your Controller you can inject your validator like this:
@Autowired
private MathValidator validator;
and add this method with annotation, to show spring which form it should validate. Name in annotation is name of the parameter in controller method.
@InitBinder("request")
private void initBinder(WebDataBinder binder) {
binder.setValidator(routeValidator);
}
Lets focus on the controller method. We have here parameter annotated with @Valid. Spring will call validate method from the class you've already implemented. It is obligatory to have the second parameter:Binding result
.
@RequestMapping(value = "/math", method = RequestMethod.POST)
public ResponseEntity calculate(@RequestBody @Valid MatchRequest request, BindingResult result) {
if (result.hasErrors()) {
return new ResponseEntity(result.getAllErrors(), HttpStatus.BAD_GATEWAY);
}
//call service,etc.
}
Also, there is another interesting tool in spring. It's annotation @ExceptionHandler
. With this annotation, you can map exceptions, thrown from controller, or service to http requests. Read more on this topic on the official website
Upvotes: 1
Reputation: 245
About your question 2 & 3, you might want to look into the Validator interface: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html
This post shows how is is used: Spring MVC: How to perform validation?
As for question 1, you can transform the errors in the BindingResult to a JSON and use this on the client-side to perform useful feedback to the user.
Also, in my opinion, you should not use a HTTP failure code in that case because a user input error is not really an error, but a normal use case in your application.
Upvotes: 1