I am using <mvc:annotation-driven/> and I would like to configure RequestMappingHandlerMapping for disabling useTrailingSlashMatch. When I declare another RequestMappingHandlerMapping, I will end up 2 RequestMappingHandlerMapping. How can I configure RequestMappingHandlerMapping ?
As you have already noted, this is feasible in xml by removing mvc:annotation-driven and replacing with the entire xml equivalent:
<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="conversionService" ref="conversionService"></property>
<property name="validator">
<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
</property>
</bean>
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
</list>
</property>
</bean>
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="useTrailingSlashMatch" value="true"></property>
</bean>
Can you try with Java config to override RequestMappingHandlerMapping value
#Configuration
#ComponentScan(basePackages = "base.package.name")
public class WebAppConfig extends WebMvcConfigurationSupport {
#Override
#Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping rmh = super.requestMappingHandlerMapping();
rmh.setUseTrailingSlashMatch(false);
return rmh;
}
}
If you want a solution that doesn't involve duplicating functionality in Spring then you can override the DisplatcherServlet. in Servlet 3.0 container this might look like:
#WebServlet(name="spring-dispatcher", loadOnStartup=1, urlPatterns={"/"},
initParams={
#WebInitParam(name="contextConfigLocation",
value="/WEB-INF/spring/spring-dispatcher-servlet.xml")})
public class MyDispatcherServlet extends DispatcherServlet {
#Override
protected void initStrategies(ApplicationContext context) {
super.initStrategies(context);
for (RequestMappingInfoHandlerMapping handlerMapping
: BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, RequestMappingInfoHandlerMapping.class, true, false).values()) {
handlerMapping.setUseTrailingSlashMatch(false);
}
}
}
Add the following to your spring configuration file to toggle the useTrailingSlashMatch field.
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="useTrailingSlashMatch" value="true">
</property>
</bean>
Related
In an old spring application, I have the following in the applicationContext.xml file, now I need to rewrite it in Spring Boot?
How do I do that in Spring Boot?
Any help or hint would be greatly appreciated it?
Spring applicationContext.xml
<bean id="dealTicketDAO" class="SqlMapDealTicketDAO">
<property name="dealTicketMapper" ref="dealTicketMapper" />
</bean>
<bean id="dealTicketMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="DealTicketMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="dealTicketService" parent="baseTransactionProxy">
<property name="target">
<bean class="DealTicketServiceImpl">
<property name="dealTicketDAO">
<ref local="dealTicketDAO"/>
</property>
</bean>
</property>
</bean>
Create a class annotated with #Configuration
the dependency is (org.springframework.context.annotation.Configuration)
and for each bean declaration in your XML file create a #Bean (org.springframework.context.annotation.Bean) method within this class.
#Configuration
public class MyConfiguration {
#Bean
public MapperFactoryBean<DealTicketMapper> dealTicketMapper() throws Exception {
MapperFactoryBean<DealTicketMapper> factoryBean = new MapperFactoryBean<>(DealTicketMapper.class);
factoryBean.setSqlSessionFactory(sqlSessionFactory());
return factoryBean;
}
#Bean
public DealTicketService dealTicketService(DealTicketDAO dealTicketDAO){
return new DealTicketServiceImpl(dealTicketDAO);
}
this should surely help you
Posted my current configuration
#Configuration
public class Config {
#Value("${spring.datasource.primary.jndi-name}")
private String primaryJndiName;
#Value("${spring.datasource.secondary.jndi-name}")
private String secondaryJndiName;
#Primary
#Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability
public DataSource primaryDs() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource(primaryJndiName);
}
#Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability
public DataSource secondaryDs() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource(secondaryJndiName);
}
}
I implemented this way and it is working
you can put your jndi values in one properties file and then load that property file in your bean defination.xml
jndi.properties
#JNDI property for job repository
job.repository.db.connection=jdbc/pgDB
#JNDI property for application
application.db.connection=jdbc/db2Conn
Bean-defination.xml
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:/properties/jndi.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
<bean id="jobRepoDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${job.repository.db.connection}" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${application.db.connection}" />
</bean>
I'm trying to inject a list of Class. I want a list of classes, not objects.
My class looks like this:
public class CodeServiceImpl{
private List<Class<?>> codeList;
// getter and setter
My spring configuration file (I'm not using annotations but xml) is
<bean id="myCodeServiceImpl" class = "net.croz.service.CodeServiceImpl">
<property name="codeList">
<list>
<ref bean="myAddress"/>
<ref bean="myCity"/>
<ref bean="myCountry"/>
</list>
</property>
</bean>
<bean id="myAddress" class="java.lang.Class" factory-method="forName">
<constructor-arg value="net.croz.model.Address"/>
</bean>
<bean id="myCity" class="java.lang.Class" factory-method="forName">
<constructor-arg value="net.croz.model.City"/>
</bean>
<bean id="myCountry" class="java.lang.Class" factory-method="forName">
<constructor-arg value="net.croz.model.Country"/>
</bean>
But the list codeList isn't being populated. It ends up being a null object. Thank you for your help.
Actually it works as is:
<bean class="com.my.proj.Foo">
<constructor-arg value="java.lang.String, org.springframework.util.StringUtils, byte[]"/>
</bean>
where Foo is:
public class Foo {
private final List<Class<?>> codeList;
public Foo(Class<?>... codeList) {
this.codeList = Arrays.asList(codeList);
}
}
The ConversionService does the stuff for converting comma-separated string to the Class<?>[] and tries to resolve each class on its own using BeanClassLoader
Tried to configure Spring for tests with hibernate and transactions. Getting bean from app context which is marked with #Transactional transaction isn't intercepted. What I could miss in configuration?
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<import resource="spring-dao.xml"/>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="userService" class="com.test.service.UserServiceimpl">
<property name="userDao" ref="userDao"/>
</bean>
public interface UserService {
public abstract User loadUserById(long userId);
#Transactional
public abstract void doSomething();
}
public class UserServiceimpl implements UserService {
#Override
public void doSomething() {
User user = loadUserById(1);
user.fillUpMoney(999);
userDao.update(user);
throw new RuntimeException("Shpould be rollback");
}
Don't annotate the abstract method as transactional, annotate the concrete implementation.
Do not user BeanFactory ;)
http://forum.springsource.org/showthread.php?122292-Sprinng-doesnt-intercept-transaction
Hallo all:
I read the spring reference about this point.
I would choose to use the #PersistenceContext in my DAO to inject a shared transactional entity manager, but since I use the GenericDaoJpaImpl pattern over two entityManagerFactories that point to 2 different persistence units I cannot use it.
So right now in my application I have this configuration:
entityManagerFactoryies:
<bean id="entityManagerFactoryIban0" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/contratto-persistence-iban0.xml" />
</bean>
<bean id="entityManagerFactoryCont0" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/contratto-persistence-cont0.xml" />
</bean>
<bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
<property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
</bean>
<bean abstract="true" id="abstractDaoJpaImplCont0" lazy-init="false">
<property name="entityManagerFactory" ref="entityManagerFactoryCont0" />
</bean>
Then each of my DAOs is an instance of the GenericDaoImpl:
#Repository
public class GenericDaoJpaImpl<T, ID extends Serializable> implements GenericDao<T, ID> {
private Class<T> entityClass;
private EntityManagerFactory entityManagerFactory;
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public GenericDaoJpaImpl() {
super();
}
public GenericDaoJpaImpl(Class<T> entityClass) {
super();
this.entityClass = entityClass;
}
/**
* #see it.alten.intesasanpaolo.contratto.dao.common.GenericDao#getItemByID(java.io.Serializable)
*/
#Override
public T getItemByID(ID id) {
EntityManager em = entityManagerFactory.createEntityManager();
return em.find(entityClass, id);
}
I construct my dao via spring in this way:
<bean id="eventMessageDao" parent="abstractDaoJpaImplCont0" class="it.alten.intesasanpaolo.contratto.dao.common.GenericDaoJpaImpl">
<constructor-arg>
<value>it.alten.intesasanpaolo.contratto.domain.event.OnlineEventMessage</value>
</constructor-arg>
</bean>
Now I would like to modify the GenericDaoJpaImpl as described in the spring documentation not to be associated to the entityManagerFactory from which I have to create every time the entityManager but directly to the entityManager.
I would like to define it in the context in a way I can inject it to the correct abstract dao to be extended from every dao.
<bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
<property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
</bean>
How can I achieve this?
kind regards
Massimo
You can use SharedEntityManagerBean to construct a transactional EntityManager from the EntityManagerFactory:
<bean id="entityManagerFactoryIban0"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
</bean>
<bean id="entityManagerIban0"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactoryIban0" />
</bean>
<bean abstract="true" id="abstractDaoJpaImplIban0" lazy-init="false">
<property name="entityManager" ref="entityManagerIban0" />
</bean>
You can provide the persistence unit name in the xml configuration, using the SharedEntityManagerBean, like below:
<bean id="testDao" class="com.test.persistence.dao.BaseDAO">
<property name="entityManager">
<bean class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="persistenceUnitName" value="persistence-test-unit" />
</bean>
</property>
</bean>
of course, you can have the SharedEntityManagerBean as a separate bean
Here, I m injecting entityManager into BaseDAO as you're doing using #PersistenceContext(unitName="...")