Spring 3 MVC Multiple view resolvers(Jsp and Velocity) - spring

Because of some business/technical constraints we should use spring3 MVC multiple view resolvers(JSP and Velocity). I tried to search on net on this but i couldn't find perfect solution. May be someone else had experienced the same scenario. So Could you please let me know is it possible to use both JSP and Velocity as vew resolvers in the SPring3 MVC application
All help is appreciated.

Spring support multiple view resolvers. You chain view resolvers by adding more than one resolver to your application context and use the order property to specify ordering.
you can use chain these jsp and velocity like -
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="2" />
</bean>
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value=""/>
<property name="suffix" value=".vm"/>
<property name="order" value="1" />
</bean>
Find out more about view chaining here

Yes, it is possible to configure multiple view resolvers, just ensure that you order the Velocity one higher than the JSP based view resolver:
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver" p:order="0">
...
</bean
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="1">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

Related

`mvc:message-converters` ignored in Spring 5

We used to have the following configuration to customize our message converters in Spring 4:
<mvc:annotation-driven conversion-service="conversionService" content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="myObjectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
But after migrating to Spring 5, the above configuration has lost any effect (the default message converters take place).
If I define the bean explicitly, it works:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="objectMapper" ref="myObjectMapper" />
</bean>
</property>
</bean>
<bean class="org.springframework.http.converter.ByteArrayHttannotation-drivenpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
</list>
</property>
</bean>
Any idea why the mvc:message-converters tag stopped working?
ps. While debugging the issue I also noticed several instances of RequestMappingHandlerAdapter being instantiated in all cases, even though I would expect them to be a singleton. The latter significantly obscures debugging, since I'm not sure which is the right one to attribute message converters to to investigate.
pps. Another report of this issue:
https://stackoverflow.com/a/49156186/657723
In this case mvc:message-converters was overridden by another, empty mvc:annotation-driven which happened to be unnoticeably included down the chain of child xml inclusions.
In any case, the major problem was the silent override, which should have better be an error.

Spring and quartz integration with dynamic values

I am new in quartz
I am trying to integrate spring with quartz i want to take repeatInterval and startDelay dynamically is it possible.
<bean id="sampleJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="sampleJobBean" />
<property name="repeatInterval" value="5000"/>
<property name="startDelay" value="4000" />
</bean>

Spring multiple transaction managers, single transaction

I have a complex situation where I have to use 2 different databases, there for I use 2 different transaction managers. Is there a way in Spring to link these transaction managers to work in a single transaction ? In case of an exception on the second dataSource changes on the first should be rolled-back.
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#dummyHost:1521:dummySID" />
<property name="username" value="owner" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#dummyHost2:1521:dummySID2" />
<property name="username" value="owner" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource2" />
</bean>
You can use Spring's JtaTransactionManager to make sure both DBs are transacted with a single transaction manager.
Note, you would have to choose an underlying implementation which can either be a container's one: e.g. WebLogic, WebSphere and OC4J, etc.. or a stand alone, even an open source one: e.g. Atomikos.
HOWEVER
XA transaction management complicates things (configuration / performance / problem resolution / maintenance / etc.). And in a lot of cases, it can be avoided by clever patterns.
To get a solid understanding on whether you need to use XA ( e.g. distributed ) transaction manager, take a look at this fantastic article by Spring's own Dave Syer: Distributed transactions in Spring, with and without XA
You need a global transaction manager which supports 2-phase-commit (XA). Several independent and free ones are available. I've used Bitronix in a Spring-based project, but there is also Atomikos, and probably others. See http://en.wikipedia.org/wiki/Java_Transaction_API#Opensource_JTA_implementations
For routing through multiple datasource, You could use abstractRoutingDataSource but if you have requirements like one rollbackack affecting another you would need a JtaTransactionManager for distributed txn management .

Spring, Websphere, JMS and Eclipselink Issue

I have an application that runs inside of Websphere, and I am having an issue with persisting JPA entities.
Previously, the application was setup with RESOURCE_LOCAL persistence units, with the Spring JpaTransactionManager, and transactions that were committed explicitly in code.
TransactionStatus transactionStatus = transactionManager.getTransaction( new DefaultTransactionDefinition() );
try {
entityManager.persist( someJpaEntity );
}
catch( Exception exception ) {
transactionManager.rollback( transactionStatus );
throw exception;
}
try {
transactionManager.commit( transactionStatus );
}
catch( TransactionException exception ) {
exception
}
I am working on an enhancement to the application that will allow calls through a Message Driven Pojo linked to a Websphere Queue. I was able to setup a configuration through spring that will allow my application to receive messages through a JMS queue. The spring config looks like:
<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="QueueConnectionFactory"/>
<jee:jndi-lookup id="jmsQueue" jndi-name="DIQueue" />
<!-- A dynamic resolver -->
<bean id="jmsDestResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver"/>
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="jmsConnectionFactory"/>
</property>
<property name="destinationResolver">
<ref bean="jmsDestResolver"/>
</property>
</bean>
<bean id="messageListener" class="my.app.FileMessageListener" />
<bean id="exListener" class="my.app.JmsExceptionListener" />
<bean id="msgListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="destination" ref="jmsQueue" />
<property name="messageListener" ref="messageListener" />
<property name="transactionManager" ref="transactionManager" />
<property name="taskExecutor" ref="myTaskExecutor" />
<property name="exceptionListener" ref="exListener" />
</bean>
<bean id="myTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
<property name="workManagerName" value="wm/default" />
</bean>
Not sure if there is an issue with my spring setup, but I do receive messages through my Active MQ broker, so that part I seem to be good with.
Now, the issue is, that when I get a message in through JMS, I would call the above code to insert the JPA entity. When the code would run, I would get the message "unable to commit a one phase resource in a two phase transaction", or something similar. What I came to understand is that the Spring JpaTransactionManager does not work with XA or JTA transactions.
So, I worked on moving to the Spring JtaTransactionManager.
I changed everything I Could think of over to use JTA, here is where I declare my transaction manager:
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>
Updated my persistence XML:
<persistence-unit name="AppUnit" transaction-type="JTA">
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
<jta-data-source>java:APPDS</jta-data-source>
And still, nothing works. My code runs without exception, but nothing gets persisted to the database. The message gets pulled off of the JMS Queue, but no data.
Any suggestions?
I finally got this working, and figured I would post the answer.
There are actually 2 pieces to the puzzle.
First, in Websphere, you need to go to your app server -> TransactionService, and check / enable the "Accept Heuristic Hazard" checkbox. That definitely helped. I am running WAS 7.
The second thing, is you MUST set the property eclipselink.target-server on your persistence unit or your EntityManagerFactory.
That second item definitely did the trick. I tested with the property and without it. Without it, nothing persists. With it, everything works fine.
Here is my EntityManagerFactory, I am using a property placeholder to set the value of the eclipselink.target-server property:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="MyUnit" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="databasePlatform">
<value>${app.databasePlatform}</value>
</property>
<property name="showSql">
<value>${app.showSql}</value>
</property>
</bean>
</property>
<!-- THIS DID THE TRICK -->
<property name="jpaPropertyMap">
<map>
<entry key="eclipselink.target-server" value="${app.targetServer}"/>
</map>
</property>
</bean>

Spring Vs Struts + Freemarker

For a Web application If I've choices between Spring and Struts to use with Freemarker, which one go well, Or I would rather ask, which MVC framework integrates smoothly with Freemarker?
The Spring framework provides everything you need to use FreeMarker for your view layer.
Both have pretty good freemarker support. Its easy to turn on.
Struts2 is a little more pojo based. Spring is a little closer to the servlet api. Spring's default macros in spring.ftl need a little work and you will likely need to roll your own. Some of the macros blow up if an object is not present rather than gracefully testing for it and moving on if it is not there.
I like Spring's application of validation via annotations better than Struts 2 default validation. However, persisting validation errors over redirects is easier in Struts2. For Spring you'll end up needing to roll your own solution where I feel the framework should hide more of that. Needing to use the error prone spring.bind macro with freemarker templates is more cumbersome than it needs to be.
Spring 3.1 is supposed to provide better support for this validation errors living over redirects.
Also note, with Spring I typically use more than one view resolver. e.g. I still leaving support for .jsp on.
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="ftl" value="text/html"/>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="favorPathExtension" value="true"/>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
</list>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true"/>
<property name="order" value="1"/>
<property name="prefix" value="/"/>
<property name="suffix" value=".ftl"/>
<property name="contentType" value="text/html;charset=UTF-8"/>
<property name="exposeSpringMacroHelpers" value="true"/>
<property name="requestContextAttribute" value="rc"/>
<property name="exposeSessionAttributes" value="true"/>
<property name="exposeRequestAttributes" value="true"/>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
</bean>

Resources