How to configure Bean Validation with Spring MVC - spring

I am trying to configure Spring : LocalValidatorFactoryBean to set my custom TraversableResolver
I do the following in my applicationContext.xml :
<bean id="customTraversableResolver" class="com.package.core.resolver.SimpleTraversableResolver" />
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="traversableResolver" ref="customTraversableResolver" />
</bean>
But at runtime, #Valid bean in controller are validated with default traversable resolver (from hibernate validator).
So, how to configure default bean validation configuration in spring ?

Have you tried adding validation.xml and adding the traversable resolver configuration in there? Btw, what do you want to achieve with your custom resolver?

While you’re using Spring MVC, you must register your validator in this way:
<mvc:annotation-driven validator="validator" />
If you want method-level validation, then define bean:
<!-- Enable method-level validation on annotated methods via JSR-303 -->
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"
p:validatorFactory-ref="validator" />
Then you don’t need validator.xml anymore.
Note: This works with Spring 3.2.x and Hibernate Validator 4.x.

Related

Prevent Spring from meddling with CDI annotations even for factory created instances

I have a legacy product's JAR that contain Spring (4.3.8) managed classes. I need to integrate it with CDI (JavaEE 7).
I have an interface from the legacy JAR, that is implemented by a CDI bean. The CDI bean is requested from the CDI BeanManager and returned from a factory method. The factory method is registered inside Spring XML and works as expected.
The problem occurs, when a Spring bean of the legacy JAR depends on the implemented interface. Spring than injects the CDI implementation instance and scans the class it for known annotations, namingly #Inject. It then tries to resolve the dependency, which doesn't work since the dependency is not available to Spring.
I already tweaked context:property-placeholder excludes, but that changes nothing.
So how can I tell Spring to stop trying to inject something in my factory produced bean instance?
I finally was able to solve (work around) the problem. I had to remove all CDI-Annotations in the legacy JAR (by replacining them with their Spring counterparts), so spring would any longer work.
Then I added the following XML block to the applicationContext.xml of my CDI WAR:
<context:component-scan annotation-config="false" base-package="com.example">
</context:component-scan>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
<property name="autowiredAnnotationTypes">
<set>
<value>org.springframework.beans.factory.annotation.Autowired</value>
<value>org.springframework.beans.factory.annotation.Value</value>
</set>
</property>
</bean>
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
<bean class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>org.springframework.beans.factory.annotation.Qualifier</value>
</set>
</property>
</bean>
Basically that drops the support for #Inject, etc. from Spring and leaves it where it belongs: CDI.
It's a bit easier.
AutowiredAnnotationBeanPostProcessor is already a bean, so you can configure it before Spring starts to scan with a ServletContextListener to exclude #Inject annotations. At least from Spring 4.1+, AutowiredAnnotationBeanPostProcessor has a method setAutowiredAnnotationTypes, e.g.:
#WebListener
public class ApplicationConfigListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
ApplicationContext appCtx = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<Class<? extends Annotation>>();
AutowiredAnnotationBeanPostProcessor bean = appCtx.getBean(AutowiredAnnotationBeanPostProcessor.class);
autowiredAnnotationTypes.add(Autowired.class);
autowiredAnnotationTypes.add(Value.class);
bean.setAutowiredAnnotationTypes(autowiredAnnotationTypes);
}
}
You could use a SpringBeanAutowiringInterceptor too.
This is explained here.

Working of Resource Injection #Resource and Spring Framework?

I want to understand how the annotation works. I have this piece of code which I have used in a simple Spring project.
#Resource(name="dataSource")
private DataSource dataSouce;
The dataSource I have defined in an XML config file:
<!-- The Apache DBCP implementation of DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
Other snippet from spring xml config file
<context:annotation-config /> <!-- This enables the annotation's actions, else annotations don't do their work. -->
<context:component-scan base-package="com.example.dao.jdbc.impl"/> <!-- This is for component scan -->
<bean id="jdbcOperImpl" class="com.example.dao.jdbc.impl.JdbcOperImpl"/>
As I understand the Resource annotations comes from javax.annotation.Resource. I looked its source code, and I notices the annotation is defined by JDK SE, and it is just a simple definition of an annotation. How does this do the injection? Does Spring Framework use this annotation and does Injection? How is #Resource annotation and Spring framework related?
Actually Spring supports two types of annotations which are Spring based annotations and Java based annotations. For dependencies you can use #Autowired that completely spring annotations.
#Resource and #Inject are the standard java based annotations. For more clarity see this link http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/

How would I make this bean in JavaConfig, I dont want to use XML with Spring anymore

I am working on a project and I need to set the following bean and property but I dont want to do it in XML.. I want to do it in JavaCofig style.. Can someone please show me how I would do this in javaconfig stlye
<!-- Spring Configuration needed to avoid URI using dots to be truncated -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="useDefaultSuffixPattern" value="false" />
</bean>
Something like this should work:
#Bean public DefaultAnnotationHandlerMapping defaultAnnotationHandlerMapping(){
DefaultAnnotationHandlerMapping bean = new DefaultAnnotationHandlerMapping();
bean.setUseDefaultSuffixPattern(false);
return bean;
}
You can see my sample spring MVC app using code config here https://github.com/robhinds/spring-code-configuration-webapp/blob/master/src/main/java/com/tmm/web/configuration/WebMvcConfiguration.java

how Spring MVC find its handler mapping

in Spring MVC we can configure handler mapping as bean.but how spring examine what is the handler mapping we mentioned in xml?
simpliy
<bean id="simplehandler" class="" />
do we need to specify "simplehandler" bean id to somewhere for spring to identify bean handler?
First thing that must be clear is that: Spring has several handler mappings.
And the "DefaulAnnotationHandlerMapping" is activated by default (See DispatcherServlet.properties in the Spring distribution or just google for it. All default handlers are listed there). Spring will choose "DefaulAnnotationHandlerMapping" by default.
If you want Spring to use another handler mapping strategy, you have to tell him explicitly
e.g.:
<bean class="org.blablabla......ControllerClassNameHandlerMapping" />
Note that this cancels the use of the default handler mapping strategy
You can also tell Spring to use several handler mapping strategy and prioritized them by using the order property in the mappers declaration
something like
<bean class="org.blabla....DefaulAnnotationHandlerMapping" >
<property name="order" value="0"/>
</bean>
<bean class="org.blablabla......ControllerClassNameHandlerMapping">
<property name="order" value="1"/>
</bean>
Hope this helps. And sorry if the syntax of my bean declaration is not 100% correct. I had to write quickly ;-)

Wicket with Spring declarative transaction

It is possible to use the Spring Framework's #Transactional support outside of a Spring container. In reference documentation is chapter about AspectJ aspect. I'm trying to use it in my wicket application, but with no positive result.
application-context.xml:
<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj" />
<context:annotation-config />
<context:component-scan base-package="com.wicket.app"/>
<context:spring-configured />
<bean id="annotationTransactionAspect" factory-method="aspectOf"
class="org.springframework.transaction.aspectj.AnnotationTransactionAspect">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
In my form class annotated by #Configurable, I have:
#Transactional
public void process(IFormSubmittingComponent submittingComponent) {
super.process(submittingComponent);
getDao().getEntityManager().flush();
}
Stack trace:
org.apache.openjpa.persistence.TransactionRequiredException: Can only perform operation while a transaction is active.
You might be able to get this working using AspectJ load-time-weaving, but that's a very complex solution for a simple problem.
If you need declarative transactions, then I suggest you move the transactional logic from the wicket component down into a Spring bean, and invoke the Spring bean from the wicket object. The Spring bean would have the transactional annotations, and would be proxied correctly by the Spring container.
I have no experience with Wicket. But is your 'form class' (the one that contains method annotated with #Transactional) Spring managed code? i.e. Who creates the instances of the class?
If it's not, that Spring will not provide #Transactional support (neither will #Autowired work, etc).

Resources