I have a Spring application with a ContextFactoryBean defined as such:
<bean id="adServerContext" class="com.intentmedia.springframework.jetty.ContextFactoryBean">
<property name="contextPath" value="/initalpath"/>
<property name="filterMappings">
<map>
<entry key="/*">
<list>
<ref bean="filter1"/>
<ref bean="filter2"/>
</list>
</entry>
<entry key="/myServlet">
<list>
<ref bean="filter1"/>
<ref bean="filter2"/>
</list>
</entry>
....
</property>
<property name="servletMappings">
<map>
<entry key="/myServlet" value-ref="myServlet"/>
....
</map>
</property>
</bean>
So my servlet is at http://example.com/initialpath/myServlet. I'd like to define an synonym route so I can go to http://example.com/optionalpath/myServlet and refer to the same servlet. Can I define multiple paths without duplicating the entire context code block?
I'm using Spring 2.5.6.
Servlet specification allows for such configuration:
http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getContextPath()
It is possible that a servlet container may match a context by more
than one context path. In such cases the
HttpServletRequest.getContextPath() will return the actual context
path used by the request and it may differ from the path returned by
this method. The context path returned by this method should be
considered as the prime or preferred context path of the application.
I am also pretty sure that Jetty will allow such configuration. So the question is whether your framework can support that... but I doubt that anyone here will know what the proprietary factory bean is doing.
Related
I am new to java AOP. I am supposed to convert the following xml config to java annotation config in my spring boot application. May I know how exactly to convert this xml config to java annotation config:
I think none of the examples that I saw in stackoverflow match the pattern I am trying to convert.
<bean id="xyzRestTemplate"
class="org.springframework.web.client.RestTemplate">
<constructor-arg ref="xyzClientHttpRequestFactory" />
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="jaxbDataMarshaller" />
<property name="unmarshaller" ref="jaxbDataMarshaller" />
</bean>
</list>
</property>
<property name="interceptors">
<list>
<bean class="com.example.XYZHeaderRequestInterceptor" />
</list>
</property>
</bean>
<bean id="jaxbDataMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPaths">
<list>
<value>com.a.b.c.d.v2</value>
</list>
</property> </bean>
When people talk about converting from XML they don't mean necessarily doing the same thing exactly. What makes Spring Boot attractive isn't just that a configuration is a java class.
You should convert this to use RestTemplate https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-resttemplate.html
Then you just build the RestTemplate using the builder to have the JaxB marshaller and the interceptor you want.
Rest Template - XML Indentation
A nice testcase that passes with XML and passes with #Configuration classes will prove you got it right.
For thread safety issue occurred, we are converting our singleton beans as prototype. But in one scenario we still need same object (with in that thread) for multiple map item. But prototype is giving different object (of course it will). I'm not sure how to achieve it.
For e.g. in below bean A, B1 and B2 are referred twice (which are prototye beans). New B1 and B2 object is getting created each time with in same thread. I want only one B1 and B2 object in the same thread even though I referenced it twice. If B1 and B2 is singleton it will be same across al thread which should not be happening. Could you please provide some idea on how to achieve it.
<bean id="A" class="mypackage.foo" scope="prototype">
<property name="myMap">
<bean class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="targetMapClass">
<value>java.util.HashMap</value>
</property>
<property name="sourceMap">
<map>
<entry key="KEY1">
<ref bean="B1"></ref>
</entry>
<entry key="KEY2">
<ref bean="B2"></ref>
</entry>
<entry key="KEY3">
<ref bean="B1"></ref>
</entry>
<entry key="KEY4">
<ref bean="B2"></ref>
</entry>
</map>
</property>
</bean>
</property>
If you are developing a web application, you may consider using request scope if you handle a http request in a single thread. If not, you may want to register the SimpleThreadScope and use that to declare your beans.
Based on Apokralipsa suugestion, added below bean and then used the thread as scope which solved the issue.
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
Inside a web application, I'm using dozer mapper (5.3.2) to perform some object to object mappings.
DozerBeanMapper is instantiated using spring bean definition. Mapping file is provided as property in the spring context xml.
<bean id="idmToBoMPersonMapper" class="org.dozer.DozerBeanMapper" lazy-init="false" scope="singleton" >
<property name="mappingFiles" value="config/IiIdmToBoMPersonMapping.xml"/>
</bean>
Mapping is working, but according to logs, instance of DozerBeanMapper is created every time the code uses the mapper.
INFO DozerBeanMapper:166 - Initializing a new instance of dozer bean mapper.
This is concerns me, I'd expect the mapper to be created once and only once.
I have tried to explicitly use scope="singleton" in the spring bean configuration, but that is not helping either.
Any suggestions for me to try?
I would be better to use the Spring integration with Dozer instead, namely the DozerBeanMapperFactoryBean, see here the documentation for further details:
<bean class="org.dozer.spring.DozerBeanMapperFactoryBean">
<property name="mappingFiles"
value="classpath*:/*mapping.xml"/>
<property name="customConverters">
<list>
<bean class=
"org.dozer.converters.CustomConverter"/>
</list>
</property>
<property name="eventListeners">
<list>
<bean class="org.dozer.listeners.EventListener"/>
</list>
</property>
<property name="factories">
<map>
<entry key="id" value-ref="bean-factory-ref"/>
</map>
</property>
</bean>
In my REST API I want to allow the user to set the locale using a lang parameter, i.e.
http://somehost/resource?param1=value1&lang=fr
If the lang parameter is not present in the URL then the Accept-Language header should be used and set as the Locale.
I'm using Spring's i18n features in my REST API. I have looked through the documentation and configured the necessary beans. If I send a request with the Accept-Language header it seems to work OK, when I call LocaleContextHolder.getLocale() it returns the locale I set in my header.
If I use the lang URL parameter it does not work.
How can I configure Spring to use the locale parameter too?
<bean id="localeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" >
<property name="interceptors">
<list>
<ref bean="localeInterceptor" />
</list>
</property>
</bean>
<bean id="sessionLocaleResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
<bean id="messages" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
I have two suggestions to try out. First, are you certain that the LocaleChangeInterceptor is getting invoked? Most of the configurations I've seen have an id of handlerMapping for the HandlerMapping. The other suggestion is concerning another id, namely sessionLocaleResolver, I think it should be localeResolver. I'm not sure if Spring relies on those id values or the class types by default for wiring all of this together, but it is worth a shot.
I have a Spring 2.5.x application which I'm migrating to Spring 3 and just bumped into a little problem.
I have an handler mapping like so:
<bean id="handlerMappings1" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="interceptor1" />
<ref bean="interceptor2" />
....
<ref bean="interceptorN" />
</list>
</property>
<property name="urlMap">
<map>
<entry key="/url1.html" value-ref="controller1" />
<entry key="/url2.html" value-ref="controller2" />
....
<entry key="/url100.html" value-ref="controller100" />
</map>
</property>
</bean>
and another one like this:
<bean id="handlerMappings2" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/urlA.html" value-ref="controllerA" />
<entry key="/urlB.html" value-ref="controllerB" />
....
<entry key="/urlN.html" value-ref="controllerN" />
</map>
</property>
</bean>
I'm slowly replacing both with #RequestMapping annotations with a <context:component-scan> (which basically registers a DefaultAnnotationHandlerMapping).
In Spring 3 I saw the <mvc:interceptors> tag which can be used to add interceptors to certain URLs but you can specify only one interceptor, at least that's what I see from the schema.
From what I can figure, I have to register one of these for each interceptor which will duplicate all my URLs for as many times as I have interceptors (and I don't even know in what order they will run).
On the other hand I can't add the iterceptors on the DefaultAnnotationHandlerMapping because they will run for all my controllers annotated with #RequestMapping and I don't want that.
So how can I specify interceptors is Spring 3 for some URLs, without repeating the URL's and
keeping the URL to controller mapping based on the #RequestMapping annotation?
You could have a look at the SelectedAnnotationHandlerMapping and the IgnoreSelectedAnnotationHandlerMapping classes from the springplugins project. The sources are some years old but the idea still stands.
There is a presentation on the creator's blog here: Spring Framework Annotation-based Controller Interceptor Configuration. Make sure you also read the comments to the blog post.
One option would be to create a custom interceptor which can delegate to a collection of injected interceptors.