Spring framework. Set proxy for all controller - spring

How can i set proxy for all my controllers in spring framework?
I wanna change the return expresion of my controllers.

I'm going to assume you're using Spring MVC 3.* and an XML configuration. If this is not the case, please let me know and I will update my answer accordingly.
Spring MVC provides the HandlerInterceptor interface which can be used to both pre and post process requests handled by all Controllers. I would suggest that you create and implementation of this interface and use the postHandle() method to change the output of your Controllers accordingly.
Once you have your HandlerInterceptor implementation complete, you will need to instruct Spring MVC to use it. The namespace configuration for Spring MVC makes this very easy. As an example:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.example.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
In this example I am registering a single HandlerInterceptor implemented by the class com.example.MyInterceptor. I am also configuring Spring MVC to have the HandlerInterceptor implementation work on all requests. You can of course change the mapping to suit your application needs.

Related

Spring Config Client XML equivalent of #RefreshScope

We have an existing Spring MVC application (non Spring-boot application) with all (or most) of the beans configured in the XML. We wanted to use this as a Spring Cloud Config Client (we have a Spring Boot application acting as config server).
In this regard, what is the XML equivalent of configuring the beans in XML with refresh scope (same as #RefreshScope annotation). Tried configuring the RefreshScope as bean and using scope="refresh" but could see that the beans are not reflected with new values after peforming /refresh endpoint (from actuator)
Any help on this is highly appreciated
As pointed out in other answers 'refresh' scope is just another scope. However there's an issue where the bean properties are not updated with new values after /refresh call - if you define and inject properties in XML. More on the issue here. However the bean (i.e. actually the proxy) is instantiated after each /refresh call - but you need "aop:scoped-proxy" config since bean to which you inject the 'refresh' scoped bean, could be on a different scope. i.e.
<bean name="xmlValueBean" class="me.fahimfarook.xml.XMLValueBean" scope="refresh">
<aop:scoped-proxy proxy-target-class="true" />
</bean>
Well if you want to use #RefreshScope in core Spring(also Spring MVC) as people already pointed out, you have to implement the scope yourself also.
I also had the same dilemma and I did, I also wrote a blog about it, you can find there all the implementation details.
You can also use Spring Boot Configuration Server with your Spring MVC application, if you like to.
#RefreshScope for Spring MVC
#RefreshScope is just another scope. Look at how the RefreshScope class is implemented. It is creating a new scope named "refresh".
That means you should be able to use the new scope in your XML configuration, like this.
<bean id = "..." class = "..." scope = "refresh">
</bean>

How do I add custom interceptors to my annotation scanned spring-ws endpoint

I am using Spring-ws 2.1.4.RELEASE and Spring 3.2.8.RELEASE.
I am trying to add an interceptor to my endpoint but so far no luck even though I think my setup is very basic.
In my Spring-ws XML I have:
<sws:interceptors>
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.SoapEnvelopeLoggingInterceptor"/>
</sws:interceptors>
<sws:annotation-driven/>
<context:component-scan base-package="package.with.my.endpoints" />
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
</bean>
In my Endpoint annotated bean I use the Spring-ws #Action annotation for ws addressing mapping:
#Endpoint("MedicineCardIdwsEndpoint")
public class MedicineCardIdws {
#Action("http://someuriandversion#GetMedicineCardIdws")
#ResponsePayload
public String getMedicineCard(#RequestPayload Element payload, SoapMessage soapMessage) {
return "";
}
However nothing is logged by the interceptor when I send a request for my endpoint. At first I thought I had configured log4j wrongly. However, if I create a breakpoint in the first line of org.springframework.ws.server.endpoint.AbstractLoggingInterceptor#handleRequest the breakpoint is never triggered.
Then I put a breakpoint inside org.springframework.ws.soap.server.SoapMessageDispatcher#headerUnderstood I can see that the only interceptor that is registered for my Endpoint is the org.springframework.ws.soap.addressing.server.AddressingEndpointInterceptor which got added because of the Action annotation.
I thought that any global interceptors in the XML configuration would end up being added to the interceptor chain for all endpoints? However it seems this is not the case. It is not just the logging interceptor, even custom interceptors are not added. So I must be doing something wrong.
I am fairly new at using Spring-ws - did I miss something in my config, or is there an annotation I need to add in order to add interceptors for annotation scanned endpoints?
Is there another way I can add interceptors to my interceptor chain when using component scanning and annotations for Spring-ws or do I need to configure all of it in XML in order to be certain that my interceptors are added to my endpoints?
I found that if I use #SoapAction annotation instead of the WS-Addressing #Action (bot from Spring-ws packages) my custom interceptors from the XML config will get added to the endpoint.
I also found this thread in the Spring forums suggesting a workaround if #SoapAction is not an option: http://forum.spring.io/forum/spring-projects/web-services/100060-interceptors-not-working-for-ws-addressing-endpoint-action

OpenSessionInViewInterceptor in a non web application

I have to use OpenSessionInViewInterceptor in a non-web application. I have configured OSV Interceptor as follows,
<bean id="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
I'm getting a Lazy load exception. Any pointers to where I'm going wrong? Is the configuration correct?
Or does a non-web app require OpenSessionInViewFilter instead of interceptor?
Thanks!
From the first line Java Doc of OpenSessionInViewInterceptor
Spring web request interceptor that binds a Hibernate Session to the thread for the entire processing of the request.
So if you do not have a Web Request because you do not have a web application, then this Interceptor does not helps you.
The OpenSessionInViewFilter is for only Web Applications too.
So you will need to start your Session/Transaction "By Hand", for example with #Transactional.

spring xslt view

I want to add xslt view to my spring web application. But my web application configured using spring annotations and hence it does not have any expicitly declared view resolvers. I tried to add a view resolver specially for xslt but the rest of my application becomes unresolvable. It it possible to configure xslt view only using annotations? Or may be there is another solution?
Thank you.
I would guess that it would suffice to write a ViewResolver class and annotate it as #Component, provided that you have <mvc:annotation-driven /> in your xml context.

Spring Web MVC 3.1.1 argument resolver called before interceptor

I'm configuring my Spring MVC 3.1.1 app as summarized below. Logging shows that 'MyArgumentResolver.resolveArgument' is invoked before 'MyInterceptor.preHandle'. When using both in an old fashion configuration (with exclicitly defined AnnotationMethodHandlerAdapter bean etc.) they are invoked vice versa. I read that <mvc:annotation-driven> is somehow critical, since its configuration does not complement other settings of mvc: namespace. Am I facing the same problem?
<mvc:annotation-driven>
<mvc:message-converters>
...
</mvc:message-converters>
<mvc:argument-resolvers>
<bean class="[...].MyArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/home/**" />
<bean class="[...].MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
Many Thanks!
Spring 3.1 with <mvc:annotation-driven> uses a different set of classes for handling requests - e.g., AnnotationMethodHandlerAdapter is replaced with RequestMappingHandlerAdapter. You can read more about that here: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-31-vs-30
In order to work properly with those classes, they've added a new HandlerMethodArgumentResolver that supersedes the old WebArgumentResolver interface. However, I believe that Spring will automatically try to "upgrade" old WebArgumentResolvers by wrapping them in an AbstractWebArgumentResolverHandlerAdapter, which is the behavior that I was seeing during the process of upgrading. The JavaDoc for AbstractWebArgumentResolverHandlerAdapter says:
Note: This class is provided for backwards compatibility. However it is recommended to re-write a WebArgumentResolver as HandlerMethodArgumentResolver. Since supportsParameter(org.springframework.core.MethodParameter) can only be implemented by actually resolving the value and then checking the result is not WebArgumentResolver#UNRESOLVED ...
After stepping through the code, I think what may be happening in your case is that it the new classes call the supportsParameter function before executing preHandle in the interceptors, but the implementation of AbstractWebArgumentResolverHandlerAdapter actually calls the resolveArgument method and checks for 'UNRESOLVED' as the return type in order to determine if the argument resolver supports the given argument, which would give the appearance of them being called out of order.
I suspect if you rewrite your argument resolver to implement the new HandlerMethodArgumentResolver interface, it will solve your problem.

Resources