Spring annotation for making two fields mandatory out of four data fields - spring

I have four data fields and i have to make sure that i receive data for at least two fields out of four. I am using spring 3 mvc and i wanted to know that if we have any annotation availabe in spring which can be used to group this not null logic across four fields.

Yes, You can do it by annotation #NotEmpty of Hibernate Validator it will check value to be not null and size is > 0
This annotation is given on fields of bean for which you need to make it required fields.
On client side if your are using Spring form tag than there is attribute modelattribute=BeanName which map your form fields to Bean fields.
On controller side you need to validate this bean before proceed it further, for this you need to include #valid annotation before your bean object argument in controller as show below
public String submitForm(#Valid MyBean myBean, BindingResult result, Model m)
{
if(result.hasErrors()) {
return "formPage"; //return to error page or display error on client side
}
m.addAttribute("message", "Successfully saved form: ");
return "formPage";
}
result.hasErrors() return true if fields value in invalid as per validation define in your bean class. It return false if all values are correct.
Here is complete example on Validate Form fields in Spring MVC.

This can be achieved by simply creating a custom validator annotation in spring

Related

POST / GET Request Param Validation in Spring Boot

I am using spring boot. I want to validated the POST request params. So I have gine through #Validated annotation but this require creating a different class for Every API. How should I write my code?
As for example, this is my api
#RequestMapping("/tags/{tagId}/{tagParentId}")
public Response<Demo> a(#PathVariable int tagId, #PathVariable int tagParentId){
... code
}
#RequestMapping("/data/{courseId}/{instId}")
public Response<Demo> b(#PathVariable int courseId, #PathVariable int instId){
... code
}
How should I change my code to add params validation for there API's such that I do not need to create two different validation class? Just one class and then I can add different functions for different API's.
#Validated should be used, to check that a parameter is syntactical correct.
As you are using int values, this is already done by spring.
If tagId is not a valid int, the client will already receive a Http error code.
The validation, whether there is a tag with the given tagId is implicitly done in your code, you do not need an additional validator for that.
If you read tags for example from the database, and you cannot find a tag for the tagId, you should
return new ResponseEntity(HttpStatus.NOT_FOUND);
from your controller method.
You may need to change the return type of your controller method to a common superclass or just to Object, to allow returning the ResponseEntity.
Its also possible to throw exceptions in the controller methods and to configure spring to return a regarding HttpStatus.
See exception-handling-for-rest-with-spring

#Valid annotation on selected fields only

I have an account class where I use notations as follows:
#NotNull
private String name;
In account there are many fields, which I use independently in two forms. The issue is that as my first form doesn't contain
private String name;
When I submit the form the validation check fails as a field that isn't in the actual form is being checked.
Essentially the validation will always fail as the variable is in the same class but isn't being used in this particular form.
To get around this would I have to use the Spring Validator class?
Thank you.
I think you may not overcome this kind of problem while having validation annotations. But you can try these:
Create two custom classes for two forms and validate name just for one of them, and do not validate for another.
And also you can try to validate your own field manually in the controller method. Autowire validator class, and validate inside the method.
#Autowired
Validator validator;
public methodA(Model model, #ModelAttribute("modelA") ModelA modelA, BindingResult result){
validator.validate(modelA, result);
if (result.hasErrors()){
// do something
}
else {
// do something else
}
}

Spring Controller fetch query parameter for a wrapper request class

I am trying to build RESTful web service by using spring 4.0
I have a controller:
#Controller
#RequestMapping("test")
public class Controller{
#RequestMapping("fetch",method=RequestMethod.GET)
#ResponseStatus(value=HttpStatus.OK)
#ResponseBody
public ResultResponse fetchController(ResultRequest req){
if((req.getName).equals("John"))
return new ResultResponse(100);
else
return new ResultResponse(0);
}
}
and my ResultRequest.class
public class ResultRequest{
private String name;
//getter,setter
}
If I hit the url to //host//contextPath/test/fetch?name=John
the controller will return the object ResultResponse(100)
my question is, there no #RequestParam or other annotation in the request parameter,
how does the spring controller know to set the query parameter "name" as the property of wrapper class
ResultRequest ?
Thanks
Spring uses implementations of an interface called HandlerMethodArgumentResolver for resolving arguments to pass to handler methods, ie. methods annotated with #RequestMapping.
One of these is a ModelAttributeMethodProcessor. Its javadoc states
Resolves method arguments annotated with #ModelAttribute and handles
return values from methods annotated with #ModelAttribute.
Model attributes are obtained from the model or if not found possibly
created with a default constructor if it is available. Once created,
the attributed is populated with request data via data binding and
also validation may be applied if the argument is annotated with
#javax.validation.Valid.
When this handler is created with annotationNotRequired=true, any
non-simple type argument and return value is regarded as a model
attribute with or without the presence of an #ModelAttribute.
Spring registers two objects of this type. One to handle parameters annotated with #ModelAttribute and one to handle ones without.
Further reading:
Form submit in Spring MVC 3 - explanation
An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the #RequestBody or the #RequestPart arguments

Spring Custom Validation With Dynamic Values?

I have a form that has two fields:
<input id="password"...
<input id="confirmpassword"...
I have a form binding object that binds to these two variables.
class FormBindingClass
{
private String password;
private String confirmPassword;
......
......
}
Now I validate the above two fields using #NotEmpty and #Pattern validators, however I need to make sure that confirmPassword matches the password on the server side!
If it does not then I need to fail the binding result and show the error back to the user. How can I accomplish this? I explored making custom annotations something like:
#MustMatch(password)
private String confirmPassword;
But I cannot pass dynamic values to annotation can I? How can I solve this tricky issue.
This is a validation at your dao layer andfor which ina general case you would throw an exception to the web layer and handle apprppriately.So you have to manually validate this in your business logic and construct the error response at the web layer.
The spring MVC validations are basically for form backed data and which doesn't have any business logic dependency.

Spring-MVC bean Validation Type mismtach error

I am trying to validate an object using Spring JSR303 validation, i have a form object which have some nested objects along with some form properties here is my Form signature
public class PaymentDetailsForm
{
private AddressForm billingAddress;
// other properties and getter and setters
}
In my AddressForm bean i have used Bean validation annotations to validate data, but i am not using any #Valid annotation inside my PaymentDetailsForm for billingAddress.
This is the signature of my Controller method
public String createUpdatePaymentInfos(final Model model,
#ModelAttribute("paymentInfo") #Valid final PaymentDetailsForm form, final BindingResult bindingResult)
{
}
If i am sending correct data from the form everything is working perfectly fine, but if i omit any field from billingAddress which is marked as required or not null i am getting following binding error exception
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'paymentInfo' on field 'billingAddress':
rejected value [com.xxx.storefront.forms.AddressForm#e39f6f1,true];
codes [typeMismatch.paymentInfo.billingAddress,typeMismatch.billingAddress,typeMismatch.com.xxx.storefront.forms.AddressForm,typeMismatch];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
codes [paymentInfo.billingAddress,billingAddress]; arguments []; default message [billingAddress]];
default message [Failed to convert property value of type 'java.lang.String[]'
to required type 'com.xxx.storefront.forms.AddressForm' for property 'billingAddress';
nested exception is java.lang.IllegalStateException:
Cannot convert value of type [java.lang.String[]] to required type [com.xxx.storefront.forms.AddressForm] for property 'billingAddress':
no matching editors or conversion strategy found]
I was expecting that since i have not used #valid annotation for billingAddress property, it should not be validated but even in case it get validated i am not able to understand above mentioned exception/error
The bindingResult that you are seeing doesn't look like it is because of validation errors, it is likely because of the binding errors - not being able to bind the UI fields to the inner billingAddress field. Even the binding errors would end up showing in the immediately following bindingresult argument like you are seeing.
That was due to some wrong mapping from UI,in my JSP page i was mapping address fields to billingAddress object but there was one hidden field like
<form:hidden path="billingAddress" id="billingAddress"/>
This was the cause of error since it was trying to send String array and Spring binding was unable to distinguish what i am trying to do

Resources