I need a quick help regarding validation check in Spring MVC. I have a basic HTML form not the JSTL Tag form. How do I check or implement a straight forward data validation check in Spring MVC? One way in my mind coming right now is to use regex to verify the user name is alphanumeric [a-zA-Z0-9].
But I have seen people use Validator do this job. I want to use Validator as it seems more profession.
Second question,
I'm trying to get a Exception handling working properly but it is not working. I want the absolute basic response to happen, the response throws a HTTP.404 response. My simple method:
#RequestMapping(value="/request/view/{id}",method=RequestMethod.GET)
public String requestSubmit(Model model)
Now with my response String, how can I do it? After search on Stackoverflow. They said to create a generic class such as NotFoundException and extend it RunTimeException. But I still don't know how to I set the response intentionally to be 404 or any other response actually, even Http.BANDWIDTH_EXCEEEDED_RESPONSE
Fist thing you should know: it's better to use POST instead of GET in form submitting. Because when you use GET, all your model properties sent as url parameter and it's not a good practice.
For using validation, you can use #Valid as this:
public String requestSubmit(#Valid Model model)
Then you can use validation annotation like #NotNull, #Size, ... at every property of Model class you want to validate it.
When a user submits your form, if every form attribute has validation problem, spring throws MethodArgumentNotValidException automatically. For getting validation errors, you can use try-catch block in your controller or better way is to have central exception handler with #ControllerAdvice.
Related
a question to validation of put calls to a REST endpoint using spring boot and javax.validation (not the spring validation).
You have the following method in the resource:
#PutMapping(...)
public Response getResult(#RequestBody #Valid myBody, #PathVariable #MyIdValidation long id) {
}
When I call the method, myBody gets validated and I get a MethodArgumentNotValidException in my exception handler. But parameter id gets not validated!
Only if myBody is valid, id gets validated as well.
The only solution I found is to not use #Valid, and implement the validation of the body myself.
Are there better solutions?
TIA
Kibu
I don't think its doable by Spring MVC framework itself because framework handles #RequestBody and others like #RequestParam or #PathVariable differently by using different components. Also, both pieces need to be disconnected because you might not like to validate all arguments of a method.
#RequestBody is handled by org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor and validations are called from there & for params or path variable validations are done by org.springframework.validation.beanvalidation.MethodValidationInterceptor.
So in my opinion, method arguments of a controller method are handled one by one by framework & are disconnected in logic so these validations can't be clubbed together.
I've put some effort into this issue and started a project on github
It's possible to validate in one stop, but you need a different approach. Check out the project and test it.
Kibu
I have my regex patterns stored like:
private final Pattern regex1...
private final Pattern regex2...
As fields in my view. I have a validation check method in the view class which throws an exception to the controller when validation fails. Is this valid in MVC or not?
public void validation() throws Exception{
if(regex failed){
throw new exception("...");
}
...
}
It is always somehow up to you how you splitt the code, if there is a good reason behind your decision.
However, I would prefer to put the validation methode at least into the controller, because it looks like it will be triggered by an actionevent from a button. (Events should be handled in the controller)
What you can do, is to create a methode in your view, which shows an error message in the gui, if your validation has failed.
All this implice that also the regex is saved in the controller.
It is not good practice. Logic has to be moved into dedicated layed.
Best way is creating dedicated validator class OR create validation method of a service (if some operations like search in DB have to be done during the validation). In that way validator class can be well covered by unit tests.
#Autowire
UserInputValidator userInputValidator;
public void validation() throws Exception{
if(userInputValidator.validate(param1, param2)){
throw new exception("...");
}
...
}
While we're talking about MVC, it's always best to consider that as the app evolves, "input" may come from more than one place eventually.
User
service call
file
other
In this case we wouldn't want to build the validation mechanisms into the View or the Controller, but into another component that the Controller would just use/integrate with.
Validation can be a cross cutting concern (but not always)
Ideally we would want to avoid duplicating the validation of incoming data especially if the data is always valid in the same way. Duplicating the validation can cause inconsistencies. Imagine data being invalid from the UI, but the same data being considered "ok" from a service call.
There are a number of ways that you can separate the validation logic from your view:
Annotate beans for JSR-303
Create custom validation annotations (abstracting your defined regex's) and/or use libraries that provide some basic ones
Dedicated service
Resolving validation failures
I can see that you're throwing an exception when you have a validation failure. Consider the awesome article by Martin Fowler. The suggestion is that a validation failure can be expected and is not an Exception case. He also suggests a notification approach.
Another advantage of a notification approach is that your dedicated validation service/tier can support multiple validation failures. This would allow your view to highlight multiple fields or your API to return a list of failures.
I need to validate some simple forms in my application. In these forms I have one or two input text to validate so I'd like to not create a specific ModelAttribute class for every form. I'd like to use instead plain HTML form and use #RequestParam annotations to handle POST parameters.
Is there a way to use Spring form validation in this situation (without using model attribute) or should I implement a backing-form object and a validator for each form?
Currently it is not possible to use #Valid on individual #RequestParam, #PathVariable etc. to trigger validation. This is the relevant feature request on the Spring Issue Tracker. Let's cross our fingers for Spring 4.1!
In your case, you will either have to use #ModelAttribute, or perform custom validation inside the controller (or maybe a Spring interceptor if you want the same validation to apply to multiple endpoints)
I think you can do this with Annotation. You can specifie for your parameters annotation like :
#Size(min=3, max=5)
#NotNull
#NotEmpty
...
Without a model attribute, Spring form Validation is not possible. Because Spring Form Validation depends on Spring Form Binding, which is a linkage between form elements and Model Attribute. So how small the form may be, create a DTO(Model Attribute), bind it to form and Perform Validations.
Definitely not possible using Spring's validation API (Errors object):
java.lang.IllegalStateException: An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the #RequestBody or the #RequestPart arguments to which they apply
You could instantiate a model object, fill it with the data from the plain form and validate that object programmatically.
I have classic Spring MVC application.
I want to validate a Form using a corresponding Java Bean, annotated with JSR-303 validation annotation.
The form data is sent by an ajax call using JSON. This Json is converted to the target Java Bean with Jackson - automatically by spring:
#RequestMapping(value = ControllerConstants.CALCULATION_MAPPING_SUBMIT_FORM,method = RequestMethod.POST)
public String submitForm(#Valid #RequestBody MyFormBean bean, final BindingResult result) {
...
}
Problem is for example if I have an Integer field in my bean but, in JSON the values is not a number. In this case it cannot create the target bean, that cannot be validated. This situation cannot be solved with custom property editors, since there is no way to convert a a text that not represents an Integer to Integer.
It seems that this is solved in Grails, we get errors from validator (errors is domain object) which has to be created during the data binding. So I assume spring supports this, thus Grails just uses Spring's support)
So how to elegantly solve this situation to handle this "validation" error?
UPDATE
Actually I figured out, that is this is supported by spring if we use simple form submit. The problem is with integration of Jackson deserialized. It does not fills errors. Still how to solve this?
I see two options...
Have client side validation that would not allow the form to be submitted if the there are formatting issues.
On the server side you will have to have a mechanism of handling the exception that would catch it and report the problem back to client.
Hope that helps.
EDIT:
Well not having client side validations may not be a good user experience. Users do not want to be reminded about validation errors after they have made a server round trip. However, if this is still a constraint have a look at following url and it gives elegant way of handling such issues and reporting informative error messages.
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/
I am using Starbox in my Spring page. I want to submit the user rating so I can store it in the database and not have to refresh the page for the user. How can I have a Spring controller that accepts this value and doesn't have to return a new view. I don't necessarily need to return any updated html - if the user clicks the Starbox, that is all that needs to happen.
Similarly, if I have a form with a submit button and want to save the form values on submit but not necessarily send the user to a new page, how can I have a controller do that? I haven't found a great Spring AJAX tutorial - any suggestions would be great.
If you use annotations, perhaps the more elegant way to return no view is to declare a void-returning controller method with #ResponseStatus(HttpStatus.OK) or #ResponseStatus(HttpStatus.NO_CONTENT) annotations.
If you use Controller class, you can simply return null from handleRequest.
To post a from to the controller via AJAX call you can use the appropriate features of your client-side Javascript library (if you have one), for example, post() and serialize() in jQuery.
The AJAX logic on the browser can simply ignore any data the server sends back, it shouldn't matter what it responds with.
But if you really want to make sure no response body gets sent back, then there are things you can do. If using annotated controllers, you can give Spring a hint that you don't want it to generate a response by adding the HttpServletResponse parameter to your #RequestMapping method. You don't have to use the response, but declaring it as a parameter tells Spring "I'm handling the response myself", and nothing will be sent back.
edit: OK, so you're using old Spring 2.0-style controllers. If you read the javadoc on the Controller interface, you'll see it says
#return a ModelAndView to render, or
null if handled directly
So if you don't want to render a view, then just return null from your controller, and no response body will be generated.