Tiles ViewPreparer defined in Spring not found by Tiles - spring

EDIT: I believe it is the SpringBeanPreparerFactory property of tilesConfigurer that is responsible for making sure the preparers are available for tiles ... but it appears that it may not be working. The default for tilesConfigurer is "BasicPreparerFactory", and I see a reference to that in the server logs, I'm thinking that maybe somehow that property is not being set correctly and it's using the default, BasicPreparerFactor instead.
I'm at a complete loss with this one... ANY thoughts or advice would be appreciated.
I am simply trying to use a Tiles ViewPreparer which is defined in my Spring configuration ... that's it! But for whatever reason, the "execute" method of my ViewPreparer is just never called. The ViewPreparer IS being constructed by Spring, and my tile is being rendered, but the preparer never executes. It's like there is a broken link between Tiles and Spring that should be there ... I say I'm using "testPreparer" in tiles.xml, which is a bean defined in "applicationContext.xml", but tiles is behaving like I didn't define a preparer at all. Here's a good description of what I'm essentially trying to do.
/WEB-INF/tiles.xml:
<tiles-definitions>
<definition name="test.tile" template="testtile.jsp" preparer="testPreparer">
</definition>
</tiles-definitions>
applicationContext.xml
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
<property name="preparerFactoryClass"
value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory" />
</bean>
<bean id="testPreparer" class="TestPreparer"></bean>
TestPreparer.java
import org.apache.tiles.AttributeContext;
import org.apache.tiles.context.TilesRequestContext;
import org.apache.tiles.preparer.PreparerException;
import org.apache.tiles.preparer.ViewPreparer;
public class TestPreparer implements ViewPreparer {
public void execute(TilesRequestContext arg0, AttributeContext arg1)
throws PreparerException {
System.out.println("I executed");
}
}
struts.xml:
<package name="apps-default" extends="struts-default"
abstract="true">
<result-types>
<result-type name="tiles"
class="org.apache.struts2.views.tiles.TilesResult" />
</result-types>
<interceptors>
...
</interceptors>
<default-interceptor-ref name="defaultAppStack"/>
<package name="testPackage" extends="apps-default" namespace="/test">
<action name="create" class="testAction" method="create">
<result type="tiles">test.tile</result>
</action>
</package>

OK, problem solved. As it turns out, it was because I had the following entry in my web.xml:
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
For whatever reason, that was essentially breaking/interfering with what I defined in applicationContext.xml. I'd have to do more investigation to figure out what exactly the conflict was, but needless to say removing that entry solved the issue.
Sorry, I spent the last 2 days trying to figure this out, and I guess writing my problem on here helped me think through it. Oh well, at least this will be documented out here on S.O. in case anyone else every runs into the same issue!

Related

Can we replace Springframework annotations (#CacheConfig, #Cacheable, #CachePut) in the XMl file?

I am implementing a module with Spring Cache mechanism. The module is generic and can cache different type of entities. So I don't want to change the Java code and want the user to configure the applicationcontext.xml file accordingly. He can put the name of the different types of entities within the applicationcontext.xml and the code should work. For e.g. -
<context:annotation-config/>
<cache:annotation-driven cache-manager="cacheManager"/>
<context:component-scan base-package="com.nokia.oss.sure.adapter"/>
<bean id="NetworkEntityService" class="com.nokia.oss.sure.adapter.cache.NetworkEntityServiceImpl"/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="NetworkEntity"/>
</set>
</property>
</bean>
He may change NetworkEntity to ServiceEntity and so on.
So in the Java code I need to mention -
#CacheConfig(cacheNames={"NetworkEntity"})
Or I can put the same for every method -
#CachePut(cacheNames="NetworkEntity", key="#entity.sureName")
public Entity addEntity(Entity entity) {
return entity;
}
But as I stated earlier, I don't want to put the cache name "NetworkEntity" in the Java code, but want to put the same in the applicationcontext.xml file. Is it possible?
Furthermore is it possible to omit all the annotations in the Java file? If I just use AbstractApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); is it possible to mention in the applicationContext.xml file what are the methods where I want to apply the #Cacheable annotation for e.g.
I searched a lot, couldn't find it anywhere.
Thanks
Nirmalya
I found out the answer. We can put the following in the applicationContext.xml -
<!-- define caching behavior -->
<cache:advice id="cacheAdviceInterface" cache-manager="cacheManager">
<cache:caching cache="NetworkEntity">
<cache:cacheable method="getEntity"/>
<cache:cache-put method="putEntity"/>
</cache:caching>
</cache:advice>
In that case we don't need to put the #CacheConfig, #CachePut etc annotations within the Java file.

How to serialize JodaTime using UNIX timestamp format with Jackson

I am using
jackson-annotations-2.4.3.jar
jackson-core-2.4.3.jar
jackson-databind-2.4.3.jar
jackson-datatype-joda-2.4.3.jar
and Spring 3.2.11. I am using the joda time's DateTime format, and i want to serialize beans that have some date-times as properties. What i would like is to serialize only date-time's timestamp. Instead, jackson serializes the whole object, which leads to problems in js afterwards.
What i am trying to achieved worked when using jackson 1.8.3.
I have tried to register a JodaModule to the object mapper for MappingJackson2HttpMessageConverter, by defining this in applicationContext.xml. Even though the joda module is loaded, it doesnt seem to work.
I tried the following config:
<beans:beans>
<beans:bean id="objectMapper"
class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
p:simpleDateFormat="yyyy-MM-dd'T'HH:mm:ss.SSSZ">
</beans:bean>
<beans:bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
p:targetObject-ref="objectMapper" p:targetMethod="registerModule">
<beans:property name="arguments">
<beans:list>
<beans:bean class="com.fasterxml.jackson.datatype.joda.JodaModule" />
</beans:list>
</beans:property>
</beans:bean>
</beans:beans>
After that i tried:
What else should i try?
Nobody seems to care about this question. However, i will close it, since i have found the answer: i had to save the configuration in a xml file and import it in multiple xml's so that the config would be visible to all the involved contexts.

#Async annotations being ignored

I'm annotating methods with #Async but they seem to be ignored.
Here's my context file:
<task:annotation-driven executor="taskExecutor" />
<task:executor id="taskExecutor" pool-size="5-25"
queue-capacity="100" rejection-policy="CALLER_RUNS" />
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
When I create a runnable and auto wire taskExecutor, then call taskExecutor.execute(runnableThing) it works as expected.
However, Spring promises that if we just put #Async on a method it will functionally do the same thing. This is not happening for me (or at least the performance is nowhere near as good so I'm assuming it's not happening now that I think about it).
The method is very simple, here's some pseudo code:
import org.springframework.scheduling.annotation.Async;
#Controller
public class MyClass{
//some auto wired stuff for db persistence
#Async
void doStuff(MyObject object){
//does some stuff with object
//write object to database
//send email
}
}
Any feedback on where else to look - I imagine this is some config thing but I can't figure it out
Try <task:annotation-driven executor="taskExecutor" proxy-target-class="true" /> and add CGLIB as a dependency to the project
I am not so sure however that should be adding #Async to a controller's method. Best you add it on a service method that is called from the controller
I'm not exactly sure what your problem is, but maybe this will help.
An #Async annotated method is meant to be run asynchronously. However, you still need to invoke it. It won't just run on its own. If you need it to run on its own, use #Scheduled with an appropriate configuration.
With #Async, get a reference to the bean that contains it and invoke the method on that bean. (Because of how proxying works, you won't be able to get this behavior by calling the method from within other methods of the same object.)
Bean yourBean = ...; // get it
yourBean.asyncMethod();

What are the best practices around setting global model attributes in Spring MVC?

I have a menu that is data driven(cached) and it is a global component. I want to be able to inject the menu items for every request since every page is going to be using it. What is the best place to put it? I'm using annotation based Spring3. Best solution I can think of is using a OncePerRequestFilter and adding it there or sub-classing the Controller, but not sure how to do that with #Controller annotation.
I can think of two easy options:
Each #Controller class exposes the data as a method annotated with #ModelAttribute, e.g.
#ModelAttribute
public MyData getMyData() {
...
}
That's not really nice if you have multiple controllers, though. Also, this has the annoying side-effect of encoding the myData on to the URL for every redirect
I suggest instead that implement a HandlerInterceptor, and expose the data to every request that way. You can't use any annotation-lovin, but it's better separated from your business logic this way. This is similar to your OncePerRequestFilter idea, but a but more Spring-y.
You can implement it as a HandlerInterceptor.
See also:
MVC Simplifications in Spring 3.0
15.4.1 Intercepting requests - the HandlerInterceptor interface
Starting Spring 3.2, you can use #ControllerAdvice instead of using #ExceptionHandler, #InitBinder, and #ModelAttribute in each Controller. They will be applied to all #Controller beans.
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;
#ControllerAdvice
public class GlobalBindingInitializer {
#InitBinder
public void registerCustomEditors(WebDataBinder binder, WebRequest request) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
}
If you had started out with Spring Roo generated code, or limit the annotations scanned by component-scan using include-filter, then add the required filter in webmvc-config.xml
<!-- The controllers are autodetected POJOs labeled with the #Controller annotation. -->
<context:component-scan base-package="com.sensei.encore.maininterface" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
<!-- ADD THE BELOW LINE -->
<context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>
</context:component-scan>
I just found an answer for the very same question. It's part of my post:
Is there a way to stop Spring from adding in reference data from methods marked with #ModelAttribute into the URL on redirects?
You just need to set the expose model attributes variable to false on the RedirectView.
If you need add some global variables that every view can resolve these variables, why not define into a properties or map? then use spring DI, refer to the view resolver bean. it is very useful,such as static veriable, e.g. resUrl.
<property name="viewResolvers">
<list>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="attributes" ref="env" />
<property name="exposeContextBeansAsAttributes" value="false" />
<property name="prefix" value="${webmvc.view.prefix}" />
<property name="suffix" value="${webmvc.view.suffix}" />
</bean>
</list>
</property>

<security:custom-authentication-provider /> means?

i have a bean in xml like below
<bean id="theCustomAuthenticationProvider" class="test.custom.CustomAuthenticationProvider">
<security:custom-authentication-provider />
a.may i know what does security:custom-authentication-provider means when i put it in my bean like above?
b. do i need to create
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager"> ref to theCustomAuthenticationProvider
in the xml ?
c. if b. answer is yes, alternatively, can i use ref of theCustomAuthenticationProviderinside tag?
The idea is that marking a bean:
<security:custom-authentication-provider />
Will registor the bean as a authentication provider with the AuthenicationManager provided by spring security. You don't need b.

Resources