I have a joda datetime attribute in my request object and I have used #DateTimeFormat for the date formatting.
But when I enter an invalid date(say day as 55), it displays the whole message
Failed to convert property value of type java.lang.String to required type org.joda.time.DateTime for property request.myDate; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "55/12/2014" from type java.lang.String to type org.joda.time.DateTime; nested exception is org.joda.time.IllegalFieldValueException: Cannot parse "55/12/2014": Value 55 for dayOfMonth must be in the range [1,31]
How can I change it to a custom message as the present message is generated by Spring.
In another SO question
Spring mvc Joda Datetime converter fail if invalid date
it is asked to make entry in message.properties.
But I'm not able to understand how will it pick the message from property file as I am not doing any error.rejectValue type of thing, So how will the message be identified.
The approach you linked to in your question should work. But the message key you should use is for instance typeMismatch.org.joda.time.DateTime.
Even though you are not manually rejecting the value anywhere Spring will automatically know where to look for the message based on the rules described in the JavaDoc of DefaultMessageCodesResolver.
In the situation you describe Spring will look for following codes specifically:
typeMismatch.request.myDate - Conversion message for attribute named "myDate" on an object named "request"
typeMismatch.myDate - Conversion message for attribute named myDate
typeMismatch.org.joda.time.DateTime - Conversion message for DateTime type
typeMismatch - General conversion error message
So you can define some general typeMismatch message like Incorrect format and then define more specific messages as needed. The more specific error codes have higher priority than those below it. So if you have both typeMismatch and typeMismatch.org.joda.time.DateTime messages defined, the latter will be used.
Related
My client is asking if all validation errors can be displayed at once.
String properties are marked with [JsonRequired]. If more than one string property is set to null in the request, validation error messages are returned in the response for each of the null properties. I have a few non-nullable decimal properties, also marked with [JsonRequired]. If decimal (or any numeric, primitive, etc.) properties are set to null in the request, obviously a conversion error is returned.
The JSON value could not be converted to System.Decimal.
However, the required property errors from earlier aren't displayed anymore.
What I have tried is setting the type to decimal? and implementing IValidatableObject on my model class. Then I can check if the value is null and return a ValidationResult with the error description. Then I have the same issue here because the validation "stops" at the decimal? property.
I am having a case in which I would like to do some input validation on the #RequestParams of an endpoint.
I know about Validators and Custom Validators, and my current strategy implies creating a wrapper object around the RequestParams, a custom validator and apply class level the annotation that triggers the custom validation.
My problem is that the custom validation is implementing ConstraintValidator, which means that the validator will either return true or false, and an error will be created by Spring with some text (I also know that I can change this text). My desire, however, is to create a custom payload back to the client. An example could be
class MyError {
int code;
String message;
}
The way to return this object is through a #ControllerAdvice Error handler, which understands that a ConstraintValidationException should return my custom payload format. However, I need to return different codes and messages for different reasons on the input validation failed. For example:
A Field is empty -> code XXX
A Field is formatted incorrectly -> code YYY
As far as I know, there is little customization possible on the exception that is reachable from my #ControllerAdvice, I can get a list of errors that happened but I cannot easily determine what happened. (Technically I can, but it would have to be based on the message string, which is pretty weak).
Is there a way to provide extra data to the Exception so I can distinguish from the #ControllerAdvice what happened and create my custom error response accordingly?
Am I approaching it the wrong way?
You can intercept the BindException (https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/BindException.html) with the #ExceptionHandler. This contains detailed information about all validation errors. For example, with e.getFieldErrors() you can access all errors associated with fields.
For example, for a field
#MyConstraint
#Length(min = 3)
private String field;
that failed validation you get the following information in the exception:
Field error in object data on field field: rejected value [XY]; codes [Length.data.field,Length.field,Length.java.lang.String,Length].
Field error in object data on field field: rejected value [XY]; codes [MyConstraint.data.field,MyConstraint.field,MyConstraint.java.lang.String,MyConstraint].
From this you can see that it failed the #Length constraint and the custom #MyConstraint constraint.
when i used without validation the deatails successfully inserted into DB,But when i applied validation using spring above exception occurr.
java.lang.IllegalStateException:
Cannot convert value of type [org.springframework.web.multipart.commons.CommonsMultipartFile]
to required type [java.sql.Blob] for property 'employee_Uploadphoto'
could anybody please rectify this one?
I am new in struts2 . I have created an XML file for validations, but when I test my form I don't get the error messages that I configured in the XML file. instead I get the Struts 2 defaults messages such as this one :
invalid field value for field "capteur.ENERGIE_CAPTEUR".
Is there anyway to make struts2 prints the messages configured in the XML file instead of the default ones ?
That is not a validation error message, it is a conversion error message.
You can override the default conversion error message up to each single object, by creating an entry for it in the global .properties file, as described in Struts 2 documentation, Type Conversion Errors Handling:
By default, all conversion errors are reported using the generic i18n
key xwork.default.invalid.fieldvalue, which you can override (the
default text is Invalid field value for field "xxx", where xxx is the
field name) in your global i18n resource bundle.
However, sometimes you may wish to override this message on a
per-field basis. You can do this by adding an i18n key associated with
just your action (Action.properties) using the pattern
invalid.fieldvalue.xxx, where xxx is the field name.
If you are interested in understanding how it works in a deeper way, read the Short Story about Validation, Conversion and Friends.
I am in reference to the following method from BindingResult:
BindingResult.html#resolveMessageCodes(java.lang.String, java.lang.String)
I am trying to figure out the difference between an error code and a message code. Can someone please provide an example, especially one that would illustrate why there could be several message codes for a given error code?
Because web applications are internationalized, when you reject an object and want to have a message displayed for it, you don't use a hardcoded text because that will show the same no matter the language.
Instead, you specify an error code that later server as a key to retrieving the proper message from the bundles (and now the error code is a message code from the point of view of the method that must find the proper message text).
Your error code resolves to more message codes because Spring (based on the implementation) adds some additional ones for you. Here is a snippet from the Spring documentation:
[...] What error codes it registers is determined by the MessageCodesResolver that is used. By default, the DefaultMessageCodesResolver is used, which for example not only registers a message with the code you gave, but also messages that include the field name you passed to the reject method. So in case you reject a field using rejectValue("age", "too.darn.old"), apart from the too.darn.old code, Spring will also register too.darn.old.age and too.darn.old.age.int (so the first will include the field name and the second will include the type of the field); this is done as a convenience to aid developers in targeting error messages and suchlike. [...]
The last statement is the reason there are more message codes, to have control on the message that is displayed to the user, from a generic one (e.g. "Value required") to a more specific one given the context (e.g. "A value is required for field XXX").
The javadoc for DefaultMessageCodesResolver explains it further and gives an example:
For example, in case of code "typeMismatch", object name "user", field "age":
try "typeMismatch.user.age"
try "typeMismatch.age"
try "typeMismatch.int"
try "typeMismatch"
This resolution algorithm thus can be leveraged for example to show specific messages for binding errors like "required" and "typeMismatch":
at the object + field level ("age" field, but only on "user");
at the field level (all "age" fields, no matter which object name);
or at the general level (all fields, on any object).