I am maintaining a web app that is using Java bean validations (as part of JSR303 I believe).
Members are mapped with annotations like #Pattern and then we have a LocalValidatorFactoryBean that performs the validation. The Validator that this factory bean bootstraps is actually the Hibernate validation instance.
My problem is that my #Pattern regex needs to be loaded at runtime when my application starts up, so I cannot use the annotation.
Therefore, I'm wondering if there is an alternative way such as XML to plug in such validation?
If not, I may just have to use a separate Spring validator to do this work
I recommend creating custom validator as described in http://docs.spring.io/spring/docs/3.0.0.RC3/reference/html/ch05s07.html#validation.beanvalidation.spring.constraints. Thus you will need to check the value agains the pattern in the code of constraint validator class.
You can configure bean validation using XML for such a thing. The syntax is a lot like the JavaBean XML format and maps rather well to the hierarchical structure of the equivalent Java syntax.
Related
I have a REST API defined in a swagger.yaml. Inside there are all the fields with their specifications (eg: length, pattern, etc.). Is there a way in java to validate these fields according to their specifications without having to do it manually?
In this way I should go and set the annotation manually above each
field, I was looking for a library that would automate everything by
reading the rules on the swagger
Yes, the OpenApi tool generator is able to do that.
https://openapi-generator.tech/docs/generators/jaxrs-spec
If the option "useBeanValidation" is enabled (default value), then the javax.validation annotations will be generated in your jaxrs bean.
If you are trying to validate request bodies in controller level, you should check javax validation constrains https://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html
There are plenty of annotations such as #NotNull, #Pattern #Max etc. which will do the job
Is it possible to create a Java aspect that runs on class initialization using Spring AOP?
We have an annotation that will be used in several places, and in order to make use of the annotation we need some boilerplate code that needs to run every second (using #Scheduled). We're hoping to move that boilerplate code to another class-level annotation to make it easier to reuse.
As far as I understand, it's not possible to implement such a class-level annotation using Spring AOP since it only supports method execution (https://www.baeldung.com/spring-aop-vs-aspectj#4-joinpoints). Is there any workaround to achieve what we're hoping for? I'm aware we could use AspectJ instead of Spring AOP, but I'm reluctant to do that because it's complex to use.
Code snipped:
#Scheduled(fixedDelayString = "${app.pollable-consumer.time-interval}")
public void pollForDeletionRequest() {
log.trace("Polling for new messages");
cleanupInput.poll(cleanupSubmissionService::submitDeletion);
}
Thanks for your help.
Update: The annotation needs to be added to a library to enable it to be shared by different microservices.
We think that writing a new class-level annotation might help. It would run on class initialization, find all methods that are annotated with #PollableStreamListener, and schedule the polling to happen for each of the Kafka topics.
To slightly adjust the terminology and shift the focus, is it acceptable to bind the creation of such a construction to Spring's Application Context initialization? If so, you could create a Bean Factory Post Processor that would have been triggered for each #PollableStreamListener.
In a nutshell, BFPP runs before spring creates the beans during the application context initialization. This mechanism allows to "dynamically" create beans that in a runtime will be indistinguishable from those created by spring in a regular way, a kind of hook to the spring initialization lifecycle that you can use here.
So this BFPP and introspect the methods of your interest. Then based on the information found in the annotations / configuration This BFPP could register a Bean Definition per scheduled job of the bean (a class with all the required parameters that you could prepare as a part of the infrastructure). Then spring will read this bean definition and create the beans out of this bean definition as it usually does.
Here you can find an example of how to use this BFPP and more specifically its registerBeanDefintion method.
Is there a way to create #ConfigurationProperties beans in runtime using spring's functionality?
Let's say I want to state the prefixes in my custom annotation and create beans for them in runtime because creating them manually seems like a boiler-plate to me.
Something like this:
#MyAnnotation({
#CustomProps(prefix="foo"),
#CustomProps(prefix="bar")
})
And then in runtime, I want to have two config beans of the specified type created from properties with these prefixes.
I know I can generate code for them using an annotation processor, but maybe it's easier to achieve by spring's bean processors or something like this?
Yes! you can achieve it but you can't have class fields for each property. So, easy approach is use spring annotation processor and for fields you can use map which you could map using Environment bean.
https://www.baeldung.com/spring-annotation-bean-pre-processor blog would be helpful in understanding how it works with annotation processor.
(Here)[Spring: access all Environment properties as a Map or Properties object you can see how to get map of properties.
I've following problem, there's a regular spring model (let's call it "A") with some validations-related annotations. Next, there's a command object (regular POJO class that defines some field, one of them is object of type A). The command object implements Validator interface, to make binding and validation work in controller methods.
Question is, how to make use of annotations-configured validations inside the command object (given it implements Validator interface, hence it has supports() and validate() methods).
What I'm trying to achive is to have basic validations on model that is reused and mixed with some heavier business-logic validations in other parts of the system.
I have had the exact same problem. I wanted to use automatic annotation validation for "simple things" and then pass the complex validation logic to my custom spring Validator. But whenever I set the controller validator, all of hibernate's validation stopped working, as described at the end of this tutorial:
http://www.captaindebug.com/2011/07/applying-custom-spring-validator-to.html#.VQR0OI7F-gd
This technique should be used when you need to do ALL your
controller’s validation yourself, and you can’t or don’t want to make
use of the Hibernate’s reference implementation of a JSR 303
validator. From this, you’ll guess that you can’t mix your own custom
Spring validator with Hibernate’s JSR 303 validator. For example,
adding the built-in annotations to the Address command object will
have no effect:
You should forget about old style Spring Validator and delete "setInitBinder()" as described in this related question:
Spring MVC validator annotation + custom validation
You should then only rely on hibernate validation and JSR303.
To add a complex validation to your class (model), say you want to check two date fields - use a custom annotation constraint on class level as described in the link below.
https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/validator-customconstraints.html#section-class-level-constraints
Hope this helps.
Best Regards,
Alexander
Once look at this may this help you
Using both JSR-303 and Traditional Bean Validation?. There i have given one example for custom validation for model using custom annotation.
I have a bunch of projects which declare some spring bean files. I would like to write a "library" which supplies a utility which takes some bean names and adds some behaviour "around" the objects (example: Call Counting, Monitoring, Logging etc)
One obvious way for doing this would be to add some AspectJ annotations in the spring xml files in the projects but I would like the "utility" to search for some beans and add behaviour to them (This way the projects themselves are not aware of the utility).
The utility will be declared in the spring xml file somewhere so it has access to the ApplicationContext as it could implement ApplicationContextAware interface however I am keen on exploring how one would go about modifying behaviour of another bean in the app context programmatically. ex, something like find a bean of id "OrderService", create an aspected bean with some monitoring/call counting etc around all methods and replace that bean in the application context for "OrderService"
I know there are disadvantages with this approach but what I am after is "IS it possible to do this? And if yes how?"
If you don't want to use AOP, you can achieve this using a BeanPostProcessor. The Spring documentation states:
The BeanPostProcessor interface defines callback methods that you can
implement to provide your own (or override the container's default)
instantiation logic, dependency-resolution logic, and so forth. If you
want to implement some custom logic after the Spring container
finishes instantiating, configuring, and otherwise initializing a
bean, you can plug in one or more BeanPostProcessor implementations.
So you may create and register a BeanPostProcessor and implement the postProcessAfterInitialization(Object bean, String beanName) method to modify the methods you want to customize. Here is an example.
(But I would still recommend that you do this with AOP as this is the classical use case for it and it's much easier and more declarative. With the bean() pointcut, you can even advise beans with names matching a certain pattern.)
You can create your own BeanPostProcessor. You just have two declare it in applicationContext.xml and it will be called for each bean during initialization of beans (in fact, just before or just after). In each call you get a the actual object and its name. There, you can, for example, wrap that object depending on its name or type.