Custom Messages for validation annotaions - java

These annotations gives these default messages:
#Required //error.required
#MinLength(1) //error.minlength
#MaxLength(10) //error.maxlength
private String name;
I want to change these messages, it will be better if it will comes from messages file.
I tried:
#Required(message=Messages.get("requiredError"))
but it was saying:
The value for annotation attribute Constraints.Required.message must
be a constant expression
Any-other way to achieve this?
I am using play framework 2.3.7

The following line should work:
#Required(message="requiredError")
Assuming your messages-file (conf/messages or conf/messages.XX for the translations) contains an entry:
requiredError=My Message....

Related

How to set #NotEmpty annotation messages in Spring?

In a Java (+ Spring Boot) project, there is a notation using javax.validation as shown below:
#NotEmpty(message = "validation.product.notEmpty")
private String product;
#NotEmpty(message = "validation.username.password")
private String password;
I have a look at the usage of them, but there are some points that I could not understand:
1. Is there a special usage e.g. conditional message displaying for validation.username.password? For example if username field is null, then display this message? Or is it completely the same manner as the product field?
2. I search the project, but could not find validation.product.notEmpty or validation.username.password. So, how do they work? I think there should be a definition for these messages, but as I did not find, is it come from default messages of javax.validation?
What is the difference between #EmailRegex and #Email? And is there
any need to also use #NotEmpty with these #EmailRegex or #Email
annotations?
#Email will not throw error for an empty String. So you need #NotEmpty to be sure that this String is not empty if you always require an email to be there.
#Email will consider valid everything that is in the form blabla#blabla.blabla. If you want to further constraint this you can use #EmailRegex so that you allow only blabla#blabla.eu by defining your own regular expression.
#EmailRegex does not seem to be included in hibernate annotations or spring annotations. So it is either a custom annotation imported from somewhere else or just a custom annotation of your application. Inspect the code to see how it actually behaves but from it's name I suppose it behaves as I have explained above.
I search the project, but could not find validation.product.notEmpty
or validation.username.password. So, how do they work? I think there
should be a definition for these messages, but as I did not find, is
it come from default messages of javax.validation?
It should be with {....} so like #NotEmpty(message = "{validation.username.password}") private String password;. In that case Spring will automatically read properties from the property files and apply the value for the property validation.username.password. If it does not exist then go to either application.properties or application.yaml and add that property.
Some more notes on this last one. I have seen some strange cases in backend-frontend applications which might be your case here.
#NotEmpty(message = "validation.username.password")
The actual message thrown here when the validation fails is validation.username.password. I have seen cases where the frontend then reads that message and binds a value to this one. I have seen this to be used when frontend supports multiple languages and binds another value for each language each time. This would explain why you don't have { } or such a property in your application.
#NotEmpty(message = "{validation.username.password}")
with an existing property validation.username.password= password can not be empty
will have as a result when the validation fails the message password can not be empty to be delivered.

Injecting property in Springboot using #Value annotation

I am using Spring and Java for an application, and I want to use the #Value annotation to inject the value of the property, my use case is that I want first to check if that property exists as system property (so it takes priority), and otherwise default to a configuration property (existing in the properties file)
In the commented code you can see what I am trying to achieve, is that possible to default to something else that a simple string? If it is not, how can I achieve this?
//#Value("#{configProperties['local.datasource.username']}") THIS IS THE ORIGINAL CODE
//#Value("#{systemProperties['some.key'] ?: 'my default system property value'}") THIS IS HOW SPRING PROPOSE TO SET A DEFAULT VALUE
//#Value("#{systemProperties['some.key'] ?: #{configProperties['local.datasource.username']}}") THIS IS WHAT I WANT TO ACHIEVE, HOWEVER NOT COMPILING,
private String username;
What you are looking for are simple Property Palceholders.
While the Spring Expression Language supports the #{} syntax for rather complex expressions (ternary, calls, expressions, math), injecting property values and defaults is in most cases better done using a simple property placeholder ${value:defaultValue} approach:
#Property("${some.key:local.datasource.username}")
private String username;
Where some.key is being resolved (independent of its origin), and if that is null, Spring defaults to the value of local.datasource.username.
Please keep in mind, that even if some.key is present, Spring will throw an exception when it can't resolve your default property.
See also:
Spring Expression Language (SpEL) with #Value: dollar vs. hash ($ vs. #) and
A Quick Guide to Spring #Value

IllegalAnnotationsException: Class has two properties of same name

I am trying to develop a IBM JAX_WS web service using RSA 7.5 and Websphere 7 server. Since I am a beginner, hence I am following Java-class first approach i.e. I am creating the Java classes first and then generating the WSDL file.
When i try to create the wsdl file, i am getting an exception:
java.security.PrivilegedActionException:com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationsException
Class has two properties of the same name "planId"
My class refered here looks something like this:
public class MemberDetails{
#XMLElement(required=true)
private String planId;
//public getters and setters for the planId;
}
I dont have any idea like why is this exception happening. Via Google search I tried a few alternatives to resolve it but none of them worked for me :(
Note:
This is the only annotation I am using throughout my workspace. I am not sure if this is dependent on some other annotations or not. But I tried with a few such as #XMLElement(name="Plan",required=true), #XMLType, etc but every time I am getting this exception.
This exception is occuring during wsgen. (java.lang.reflect.InvocationTargetException)
EDIT
Basically, when we create a wsdl from java service method and open that WSDL in SOAP UI, then we get <!--Optional--> at the top of every element. I want to remove this option tag <!--Optional--> tag, hence I am trying for #XMLElement(required=true) approach so that when I open the WSDL in SOAP UI <!--Optional--> does not appears for compulsary elements.
According to my concept, #XMLElement(required=true) will set the minOccurs to 1 i.e. greater than zero and hence the optional comment will be removed from WSDL when I open it in SOAP UI. But Unfortunately its not working hence my concept is incorrect. After the WSDL is generated, I can see that the minOccurs is still 0.
Please explain how can I remove the optional tag when I open the WSDL in SOAP UI.
Regards,
By default JAXB (JSR-222) implementations process public accessor methods and annotated fields. If you annotate a field that you also have get/set methods for you will get this exception:
If you are going to annotate fields then you should specify #XmlAccessorType(XmlAccessType.FIELD)
#XmlAccessorType(XmlAccessType.FIELD)
public class MemberDetails{
#XMLElement(required=true)
private String planId;
//public getters and setters for the planId;
}
Or you can annotate the property
public class MemberDetails{
private String planId;
#XMLElement(required=true)
public String getPlanId() {
return planId;
}
}
For More Information
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
For JAXB2.0 annotating with #XmlTransient on getter or setter will prevent the conflict.
See more here: http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html

Is there a way to use JSR-303 (hibernate) annotations and modify the Message using {0} {1} syntax?

Is there a way to use JSR-303 (hibernate) annotations and modify the Message using {0} {1} syntax? It seem that using a Spring Validator gets you this:
String args[] = {"mark", "is", "cool"};
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "aboutYou", "aboutYou.required", args);
So I can change the message. However, if I use annotations, I cannot use the message args. I understand that there are limited (min, max, etc.) args to use, but we want to make a generic statement and add some text.
java:
#NotEmpty (message="validation.name.required")
private String name;
properties
validation.name.required={0} is required...
Output:
Full name is required.
In your interface:
public #interface Test{
int value() default 7;
String message() default "{MESSAGE}";
}
In your messages file:
MESSAGE=Testing param {value}
Output:
Testing param 7
As found here and here, works for validators which do not use hibernate also.
As it seems you're using Spring, this might help: http://blog.inflinx.com/2010/03/10/jsr-303-bean-validation-using-spring-3/
You can also get the annotation-parameters (like min- and max- annotation-values for #Size) from ConstraintViolation< Object> -object (javax.validation.Validator.validate(Object) -method returns a Set< ConstraintViolation< Object>>) with .getConstraintDescriptor.getAttributes(), if you want to parameterize them to the messages with the {0} {1} etc. -notation (the numbers might be something else than 0 and 1 for #Size for example, I don't have the code at hand, but I seem to recall that there was some other data "in between" in the Map that getAttributes returned).
Note that in my case I used programmatic validation (getting Validator-object from Validation.buildDefaultValidatorFactory().getValidator() and using it to validate an object with JSR-303 -annotations), extracted the needed data from the Set of ConstraintViolations (if the Set was not empty), put the data in a custom Exception-class and threw it out of the service, all the way to a org.springframework.web.servlet.HandlerExceptionResolver -implementation, that would gather the localization keys and message parameters from the exception object and localize the messages via MessageSource, so this might not be exactly what you're looking for.

Spring "typemismatch" and required fields

In the context of Spring Webflow 2.0.x......
I handle form binding "typemismatches", i.e. as a result of trying to map a String onto a Integer field, by using the following in my messages.properties
typeMismatch={0} contains invalid data.
This works fine.
The problem is that if the field that the typeMismatch error occurred on was "required" then I also receive an error for the missing required field, which is logical I guess because the value that was submitted was never bound. ("Required" being defined in a Commons Validation XML file)
So, I dont want to see the "XXX is required field" error message when the field is only missing due to the typeMismatch. How do I resolve this? I thought about overriding initBinder() on the FormAction but quickly got nowhere.....
Like Yves mentioned, among the three approaches, i have used a custom validator method and its very easy. You can use a custom validator which checks if the form field already has a xml error message of required. If the field does not have an error, then you can check for your string validation. That way it will display only one.
The other method that you could use is try a multiple xml validation, one being required and the other one being a mask which checks for a particular regular expression. In your case if your field is an integer field, then you can go and perform a mask with regex checking for only numbers. The order of mask, required or required, mask in the xml decides which message gets a higher preference.
For example:
<field property="somefield" depends="required,mask" page="2">
<arg key="somelabel"/>
<var>
<var-name>mask</var-name>
<var-value>${somepattern}</var-value>
</var>
</field>
You have many options, in order of preference:
Set selectively the message typeMismatch.target.yourFieldName or typeMismatch.int in resources files
Implement your own Validator so that you can send a dedicated message when Integer parsing will fail before the binding step
Create a BindingErrorProcessor to handle different kind of parsing issues

Categories

Resources