JSR303 Validation - Bean's property as Message Parameter - validation

In JSR303 validation,is it possible to pass the bean's property as parameter for validation message ?
Ex.
class BeanA {
private String userName;
#Min(value=15, message="Age of {userName} should be greater than {value}")
private int age;
public BeanA(String userName,int age){
//initialization
}
}
For an object BeanA("Ahamed", 12) , I should get error "Age of Ahamed should be greater than 15"

Unfortunatelly you can pass to annotation parameter only constant values. Since you need to evaluate value of message, it cannot be set as annotation parameter.
As a matter of fact, you don't really need to do this, default error message tells more or less what is going on, although it is not as informative as you would like.

Related

How does field mapping happen for a PUT request body?

I am stuck with a basic confusion which I cannot test and cannot find a straightforward answer to as well.
I have an endpoint PUT which expects an object in the body , RequestObject.
It consists of 1 field only.
class RequestObject {
String name;
}
Now from the service from which I am hitting this endpoint, the object that I am supposed to use to send in the request has 2 fields.
class Test {
String firstname;
String age;
}
If I make a request, with age as null,
Will this work ?
Since firstName and name are not the same "spellings", will the mapping happen automatically ?
I am assuming No for both but I am not sure how to confirm.
WIll appreciate if someone can point me in right direction.
Thanks
#JsonIgnoreProperties(ignoreUnknown = true)
class RequestObject {
#JsonProperty("firstname")
String name;
}
By default Spring Boot uses the Jackson library to convert to objects. You can customize it using annotations. See https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

Using parameter 1 without using parameter 0 in Spring Boot messages

In messages.properties file:
validation.title=At least {1} characters
Also LocalValidatorFactoryBean is defined:
#Bean
public LocalValidatorFactoryBean localValidatorFactoryBean(MessageSource messageSource) {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource);
return bean;
}
When I run the code I get the result:
At least {1} characters
But if I change in properties:
validation.title=At least {1} characters {0}
I get the result:
At least 20 characters title
But I do not need the 0 parameters.
Is there a way to fix this?
You're trying to access array parameters and with this approach in order to get that done and have your string interpolated you need to use the one at the index 0 and I have no idea why. There's another way though and with common annotations (haven't tried this with custom annotations) for validating forms this can be solved as follows:
// the form
public class SomeForm {
#Length(min = 4, max = 16, message="{username.length.error}")
private String username;
// other stuff
}
In the messages.properties
username.length.error = Username cannot be blank and its length must be between {min} and {max} characters.
So in the message.properties (in this case {min} and {max}) the placeholders must match the names of the params you have on the annotation.

Can #Nullable be used in place of required=false for a #RequestParam controller method parameter?

There appear to be two documented ways of marking a parameter of a Spring controller method as optional:
(1) Add required=false to the #RequiredParam annotation:
public String books(#RequestParam(name = "category", required = false) String category) {
reference
(2) Change the parameter type to Optional<T>:
public String books(#RequestParam(name = "category") Optional<String> category) {
reference
But it appears the following also works:
(3) Place the #Nullable annotation on the parameter:
public String books(#Nullable #RequestParam(name = "category") String category) {
I prefer #3, but I would feel better about using it if it were documented. I have searched for documentation, but all I can find is what is documented for #Nullable:
A common Spring annotation to declare that annotated elements can be
null under some circumstance.
I cannot find a single example showing #Nullable used with #RequestParam.
Does anyone know if and where this is documented?
#Nullable is a well-known annotation which can be applied to fields, methods, and parameters. Knowing its popularity maybe Spring doesn't mind not mentioning it. So, feel fry to use it.
Now coming to the choice of using validation: I will either go with #Nullable or required = false.
Optional<T> came in java 8 for preventing NullPointerException. So, <Optional<String> would never give you the null value, it would either return the value or the Optional.empty. And to get the value from this you would need to call an extra method get().
So, if the whole idea is to mark any query paramter as nullable, use either #Nullable or required=false

#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
}
}

databinding,validate,exception in spring mvc3

I am using the spring mvc3,and I found that I am confused with the some concepts,so I make a summary, and post it here.
Data binding.
I use struct2 before where if I have a bean in the action(i..e,named 'Person'),then when the following url is requested:
http://localhost:8080/app/form?person.id=1&person.name=xxx&pet.name=yy
Then a new instance of Person will be created and the parameters '1' and 'xxx' will be populated to this instance.
And a new instance of Pet will be created,and the name 'yy' will be populated to this bean.
This is the only way for data binding in struct2:
You specify the beanname.property in your request.
Now in spring mvc3,I know one way to binding the data:
http://localhost:8080/app/form?id=1&name=xxx&other=yy
#RequestMapping('form')
public String form(Person person,BindingResult result){
//now I get the person
}
Even it work,but I have some questions:
1) I have three parameters in the request url "name",'pass','other',how does spring know which parameters should be populated to my bean(model).
2) how about if I want to bind parameters to more than one model like the example in struct2(both person and pet)?
Furthermore,what does the modelAttribute and commandName attribute in the spring tag "form" mean?
2. Validate
For bean(ignore the getter and setter in the example):
import javax.validation.constraints.NotNull;
public class Bean {
#NotNull(message="id can not be null")
private int id;
}
I use this controller:
#RequestMapping("val")
public #ResponseBody
String validate(#Valid Bean bean, BindingResult result) {
if (result.hasErrors()) {
return result.getAllErrors() + "";
} else
return "no error";
}
I found that only the 'NotEmpty' works.
Since if I use this url:
/val?name=xxx ==> no error !! // id is null now,why it does not has error?
3. The type conversion.
Take this url for example:
http://localhost:8080/app/form?id=1&name=xxx&other=yy
Obviously it will throw 'NumberFormatException' if I set the id to string value.
Then where to catch this exception? If in the controller,then I have to write so many try-catch block in each controller.
Furthermore,the the type conversion exception do not limited to only 'NumberFormatException',it may be 'dataformaterrorexception' and etc.
But they all belongs to the type conversion,how to handle the using a common solution?

Resources