javax validation annotation for an integer - spring

I have a class User as show below.
class User {
private String name;
private Integer percent;
}
I wanted to have validation on percent field using javax annotations such that it only allows 4 values. (10, 50, 80, 100)
I know #Min, #Max, #Digit, but not sure how they serve my case.
I tried searching on https://www.baeldung.com/javax-validation but did not find any useful for my case.
I know I can create a custom validator. But is there any other way I can do this using existing annotations.
TIA !

This is pretty much a non-answer, as you said
I know I can create a custom validator. But is there any other way I can do this using existing annotations.
There is no built-in validator that checks from a list of values. The closest would be #Pattern, but every implementation that I have seen only supports CharSequence. Custom validator route is probably the way to go. I bet someone has written one, so Google is your friend.

Related

Java Bean Validation - Intercepting Validations

I have the following scenario: I am trying to process a form and the model attribute is a bean with String and Long properties. As you all guys know, bean validation offers a lot of annotation to help us determine the validity of the data.
What I am facing is that, for the case of the Long attributes, I can only use #NotNull and another annotation (I dont recall its name) to force the user to enter positive numbers. If the user enters for instance "sdf", the application throws a BIG exception. So what I would like to know is If I can intercept the form processing and validate by my own if the user entered a numeric thing before it explodes (because I cant use #Pattern)... and I cant switch that attribute to String...
Was it clear ?.
Use Spring Custom validation. That is Annotation-based validation and you have the ability to create your own custom validation logic. Spring Custom Validation In this link you can find out more examples and how to use it.

Forcing validation annotation to provide a message

I am using hibernate validator to do POJO validation, and also i have created some custom ones. Here is an example:
//lombok annotations
public class Address {
#NotNull // standard
#State //Custom created
String country;
}
We have a requirement to represents all the validations errors with specific codes rather than messages. In order to achieve this we have decided to specify codes in every annotation that we use. The above example now looks like this:
//lombok annotations
public class Address {
#NotNull(message="ERR_001")
#State(message="ERR_002")
String country;
}
But we have a problem with this approach. We could not enforce to provide a message(error code in our case) all the time in an annotation. For custom annotation, it is still ok as we do not provide a default message, but for the standard ones there is chance to miss it and a string message will silently generated if we accidentally miss to provide a custom message.
Is there a way to enforce to provide message all the time in the annotation. It will probably help to have some consistency.
To my knowledge no, there is no way to do that. Maybe your best option is to create your own annotation and make the attribute mandatory.
Sevntu-Checkstyle provides additional checks to Checkstyle, including a check that an annotation is used with all required parameters.
<module name="RequiredParameterForAnnotation">
<property name="annotationName" value="NotNull"/>
<property name="requiredParameters" value="message"/>
</module>
I could not find a good way to handle it. But for now i have implemented a test which give us some control over it. Its not the best solution but solves the issue for now.
I am using classgraph to read all the annotations on POJO classes inside a package and filtering it on javax validations and if the default messages appears to be from javax.validation, then i am adding to a list.
Later on a unit test, i am checking if this list is empty or not.
private List<String> getAnnotationProperties(String appliedOn, AnnotationInfoList annotationInfos) {
return annotationInfos.stream()
.filter(annotationInfo -> annotationInfo.getName().contains("javax.validation.constraints"))
.filter(annotationInfo -> ((String) annotationInfo.getParameterValues().getValue("message")).contains("javax.validation.constraints"))
.map(annotationInfo -> annotationInfo.getName())
.collect(Collectors.toList());
}

Update field annotated with #Value in runtime

Let's imagine we have such a component in Spring:
#Component
public class MyComponent {
#Value("${someProperty}")
private String text;
}
If we define the property placeholder:
<context:property-placeholder location="classpath:myProps.properties"/>
And myPropos.properties contains the value for someProperty the value will be injected to the text field when the context is initialized. That's quite simple and easy.
But let's say that I have a service that enables user to change the value of the someProperty:
public void changeProp(String name, String newValue);
Is there a chance I can re-inject the newValue to text field. I mean it should be quite straight forward.. Basically it's nothing different than the after-initialization injection. I can not imagine that Spring does not have support for this? Can I fire some event or something?
I could do this on my own basically, but I wander is it maybe something there already? If not does anyone know what Spring class is in fact handling the injections at the first place? I could probably reuse the code there do perform this on my own if a solution does not exists.
I expect spring does not have a support for this, because the normal injection is done while creating the bean, but not will it is put in service.
Anyway: in this blog entry "Reloadable Application Properties with Spring 3.1, Java 7 and Google Guava", you can find the idea for an solution.
The key idea is to use a post processor to build a list of all fields with property fields. And if the properties are changed on can use this list to update the fields.

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.

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