SmartValidator - manually calling validate with groups - spring

Spring 4.3.2
I need to call SmartValidator.validate() manually and I need it utilize the validation groups that I have defined on the target entity. The javadoc says this...
"This variant of validate() supports validation hints, such as
validation groups against a JSR-303 provider (in which case, the
provided hint objects need to be annotation arguments of type Class)."
void validate(Object target,
Errors errors,
Object... validationHints)
For some reason, I cannot find much information or examples on using "validationHints". So I have been trying things like the following...
validator.validate(targetEntity, errors, new Class[]{ValidationGroup1.class});
validator.validate(targetEntity, errors, ValidationGroup1.class);
So far, it just completely ignores my groupings. It always calls all validators. Any ideas?
Thanks!
===================================
Update: The javadoc also says this..
"Note: Validation hints may get ignored by the actual target
Validator, in which case this method should behave just like its
regular Validator.validate(Object, Errors) sibling."
This sounds like what's happening. But it doesn't give any clue as to why it might ignore it.

Alright then.
It seems the 'answer' is to not use Spring for this. Here is my workaround...
import javax.validation.Validator;
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation> violations = validator.validate(targetEntity, new Class[]{group1.class, group2.class});
Then I convert Set to Spring FieldErrors (since everything is already configured to run Spring). Kind of a clusterf***, but at least it's working now.

Related

How to use different error codes for validation messages?

I have a Spring Boot REST server which should return specific error codes when invalid input is provided. I don't need any i18n here, just plain English error codes like 'missing' is sufficient.
Using Spring Boot with Hibernate Validator, after validation I get a back Spring Errors object.
For each error I can get the code and defaultMessage. For a #NotBlank constraint this would return NotBlank and may not be null resp.
Basically I want to translate this error to just missing as I'm not interested in i18n translation. Also other constraints I want to more REST friendly error codes.
I though to use use a simple messages.properties or ValidationMessages.properties inside src/main/resources but this wouldn't work unfortunately. Note I tried both adding a general NotBlank=missing and specific NotBlank.entity.field=missing properties.
I'm not sure why it's not working... maybe because resolving i18n messages (in jsp world) does not go directly via Spring Errors but through the MessageCodesResolver implementation (just guessing).
Probably I could get the error code from the Spring Error and do a lookup from the message code resolver.
But I wonder why error.getDefaultMessage does not return the appropriate value form the ValidationMessages.properties.
Any suggestion is welcome.
The default message is the message as stated by the programmer. In the case of those JSR-303 annotations probably the ones as Hibernate thought of them. The default message including the code is passed to the MessageSource.getMessage method, which contains a parameter defaultMessage
When you look at the Errors object or actually the ObjectError method you will see that it implements the MessageSourceResolvable interface. This means you can just pass the error, as is, to the MessageSource, including the Locale if you want.
#RequestMapping
public Object foo(#Valid #RequestBody MyObject obj, Errors errors, Locale locale) {
for (ObjectError err : errors.getAllErrors()) {
String msg = messageSource.getMessage(err, locale);
// Do something with msg
}
}
Something like the above should resolve the message. The advantage of using the ObjectError itself is that next to the code you also have the parameters (for #Range or #Min) which you can then use in your message with placeholders.

Hibernate validator - conditionally apply validator

I want to apply certain #NotBlank annotations only if another field is false. On my current project we have to use hibernate validator, so no commons validation + valang available to solve this.
Since I'm not too fond of creating multiple custom annotations just to solve what should be an easy thing (bit bummed that this isn't part of the JSR-303 spec) I was wondering if anyone knew an acceptable way to accomplish this. I found a jar which accomplished that, but that was for hibernate 3. And due to the changes...
For this case, the suggested approach is to use class-level constraints instead Field or Property Level.
Please refer Hibernate Validator Docs
I now it is annoying. I had a scenario like this and tried something like #NotEmpty(depends="anotherField") and it was a totally failure.
Maybe some other members know another way to do this, but for now, I'm doing what Hibernate Validator says to do.

parameter validation with net.sf.oval (in play framework)

I would love to use the #NotNull annotation (or #Required or anything) for my own methods. While this works quite well in Controller and Model classes I cant get it to work in my own. This probably is more of a net.sf.oval question then play framework. But it might be connected, I don't know.
I have a class like:
#net.sf.oval.guard.Guarded
public class SimulatorWrapper {
public SimulatorWrapper setRedCode(#play.data.validation.Required #net.sf.oval.constraint.NotNull final String redCode) {
// just gessing here:
if(Validation.hasErrors()) throw new RuntimeException("invalid argument");
if(redCode == null) throw new RuntimeException("null");
// do stuff
return this;
}
}
When I call this method with a null parameter the if throws my exception, but #NotNull and #Required seem to do nothing at all. What am I doing wrong?
The play framework project came with oval 1.5, I downloaded 1.8 and added it to the classpath in eclipse just in case the old one had problems.
I'm starting the server with "play test my-server" and then I navigate to my website (not a test yet, just simple site) with my browser.
Thanks, Alex
P.S. I know the "null is evil" discussion, but I dont have access to the rest of the code so I cant change that.
The validation class is invoked to check the validation annotations by the Play framework only when a controller action is called.
Since you're not in a controller, the Validation on annotation won't be executed and the Required annotion won't be in Validation.hasErrors()
Instead of using annotation, you could use methods like:
Validation.required(redCode); //It'll check for null
And after that, call Validation.hasErrors() and it should work.
However, I don't think you should do this because the errors from Validation.hasError() should come from Validation on the controller action invocation and it can cause you side effects.
If you want to do something like your example, you should not rely on the play Validation class.
Are you sure you're using validation at the right places ?
In case anyone still needs this.
You can do validation with Play annotations in all classes exactly the same way as in controllers.
Just use validate plugin.

Best practice for validating a URL with Spring-MVC?

I am using Spring MVC for my web application.
I need to validate that the URL the user inputs is valid and was wondering if there is something in Spring that can do the basic checks for me (for example starts with http/https, has domain name etc).
ValidationUtils only contains very basic checks and I know I can write a regular expression in the validate() method however prefer to avoid it inm case someone has already done it :)
Thanks
In the past, I have always utilized Hibernate Validator. Simply annotate the appropriate field in your form bean with a #URL constraint.
If you've never used the ORM part of Hibernate before, don't let that scare you. The Validator portion is not dependent on the ORM stuff, and integrating it into Spring is very straightforward.
If for some reason you can't use Hibernate Validator... or you just want to stick with what you're comfortable with, a good place for regex's is RegExLib.com; several patterns that can match a URI are listed there.
Ended up using UrlValidator from apache commons.
I know this question is quite old, but I just need the same and I think I'll go with the PropertyEditors in SpringFramework.
More precisely there is URLEditor, which you can use to convert a String representation to an actual URL object.
Here is a link to the respective documentation:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-beans-conversion
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/propertyeditors/URLEditor.html
In my case, I think about using the following code within a Spring Validator to check whether a String entered by a user is a valid URL or not:
try {
PropertyEditor urlEditor = new URLEditor();
urlEditor.setAsText(field.getValue());
} catch (IllegalArgumentException ex) {
errors.rejectValue("nameOfTheFieldToBeValidated", "url_is_invalid");
}
However, as for now, I'm unsure whether it is possible to configure which protocol is going to be accepted as valid (i.e. URLEditor seems to also accept URLs starting with "classpath:")
Use a spring interceptor:
http://java.dzone.com/articles/using-spring-interceptors-your

Spring - data validation

I'm just wondering about data validation in Spring. Spring is offering two (maybe more) validation options. First option is to use Validator interface and create whole validation on my own. Second option is to use annotation validation (JSR 303).
And now I'm really confused :) which validation I should chose. What I need is to check if recieved Data Object is correct (by correct i mean all required fields are filled) and this can be done by JSR 303 validation or by my own validator with "Validator instance". But I also need to check if is this Data Object valid against some database constraints (validator is required to check some data in database, eq. is user with this ID registered or not ...) and this can be done only by my own validator.
I don't know which way should be the best. Combine both or create my own validator ?
I will be thankful for any advice ...
Update (relocated from comments)
Ok, I followed Ryan's example and I think I was successful. I created my own implementation of spring Validator and in this Validator I #Autowire-d javax JSR 303 instance. But there was problem with that injection. I had in my configuration and this piece of code caused some exceptions, because spring did not know which Validator I want to inject. So I removed that code.
At the end I also removed the spring Validator implementation, because I dont know where I can get Errors property, which is required as second parameter in "validate" method :). I'm triggering that validation manually from service layer and I really don't know, where I can obtain that Error object.
BTW Well, I found another solution how to implement that validation. I'm thinking about to extend my validator class by LocalValidatorFactoryBean. LocalValidatorFactoryBean class implementing both Validator interfaces (Spring Validator + JSR 303). But i'm not sure if is this good approach. This approach also require Error object, which I don't know where to find/get.
Update
The Error object is coming from "BindException".
FooObjectVO myObject = new FooObjectVO();
BindException errors = new BindException("fooObject", myObject);
They're not really separate options--more like two available implementations of validation. Since Spring's JSR 303 support also implements its own Validator interface, you don't really have to pick one or the other. You can mix and match the implementations in whatever way makes it easiest to get the job done.
In cases such as this I prefer to combine both. I like to use JSR 303 validation for whatever I can. I supplement it with my own validators.

Resources