I have kind of a problem. I need to call on each request postHandle method in this interceptor:
public class DiMenuInterceptor extends HandlerInterceptorAdapter {
@Autowired
private IDiCategoryService categoryService;
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
modelAndView.addObject("category", categoryService.getCategoryInTree());
}
}
so I put into servlet configuration this lines and everything work fine.
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:interceptors-ref="menuInterceptor" />
<bean id="menuInterceptor" class="cz.cosi.DiMenuInterceptor" />
But now I have to change configuration and use <mvc:interceptors>
With this configuration, I'm getting series of null pointer exception on modelAndView in the postHandle method because the postHandle method is called more than once per request.
<mvc:interceptors>
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptors>
With this configuration, it is working, but only for request serverAdress/anything. For request serverAdress/anything/something is postHandle not called.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*" />
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
part of servlet configuration
<mvc:annotation-driven />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:interceptors>
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptors>
<tx:jta-transaction-manager />
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
It seems, that the problem might somehow relate to resources, because with exceptions are not properly loaded images, styles, and javascript. Without mvc:resources its working correctly, but this is not a solution.
My question is, how to properly configure DiMenuInterceptor with <mvc:interceptors>
. Thanks very much for the advices.
stack:
2011-04-14 09:56:02,487 [http-8080-3] DEBUG (FilterChainProxy.java:195) ? Converted URL to lowercase, from: '/images/core/users/super_admin.png'; to: '/images/core/users/super_admin.png'
2011-04-14 09:56:02,533 [http-8080-3] DEBUG (FilterChainProxy.java:202) ? Candidate is: '/images/core/users/super_admin.png'; pattern is /images/**; matched=true
2011-04-14 09:56:02,533 [http-8080-3] DEBUG (FilterChainProxy.java:158) ? /images/core/users/super_admin.png has an empty filter list
14.4.2011 9:56:02 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet spring threw exception
java.lang.NullPointerException
at cz.cosi.DiMenuInterceptor.postHandle(DiMenuInterceptor.java:41)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:801)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:163)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at jav开发者_如何学运维a.lang.Thread.run(Thread.java:595)
Maybe I found a solution, but it is definitely not the best. For now it seems, that is working.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*" />
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/search/**" />
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/context/**" />
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/member/**" />
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
Your need to specify that your path includes subpaths: /**"
instead /*
.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cz.cosi.DiMenuInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
@see Excample in Spring Reference, Chapter 15.12.2 mvc:interceptors
The problem is that the interceptors are called when resources are requested.
This post talks about how to prevent the interceptors from being called using the xml configuration. In the accepted answer, I am not a big fan of relying on the semantic makeup of the paths (ie using .html or having page in the path). Now all developers on the team have to be aware of this when creating controllers.
I also am not a fan of the verbose bean configuration, so I have decided to add the following code to the interceptor:
if (ClassUtils.isAssignableValue(ResourceHttpRequestHandler.class, handler)) {
return;
}
// do interceptor logic here...
I had very simillar problem but with accessing to fonts for Bootstrap 3. Interceptors blocked fonts resources like 'glyphicons-halflings-regular.woff' or 'glyphicons-halflings-regular.ttf' and they were not visible in front page. I resolve my problem in following way. The definition of my interceptor look like below:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cz.cosi.DiMenuInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
And my DiMenuInterceptor class:
public class DiMenuInterceptor extends HandlerInterceptorAdapter {
private List<String> nonAuthPaths;
public DiMenuInterceptor() {
nonAuthPaths = new ArrayList<String>();
nonAuthPaths.add("/login");
nonAuthPaths.add("/resources/vendor/fonts/glyphicons-halflings-regular.woff");
nonAuthPaths.add("/resources/vendor/fonts/glyphicons-halflings-regular.ttf");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute(SessionManagement.USER_KEY);
if (user == null && !nonAuthPaths.contains(request.getServletPath())) {
response.sendRedirect(request.getContextPath() + "/login");
}
return false;
} else {
//ect ...
return true;
}
}
I had the same question too. Initial configuration:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="cn.mmd.micro.common.TokenInterceptor">
<property name="excludeUrls">
<list>
<value>/app/token</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
I changed the value "mvc:mapping", and it worked. My new configuration is as follows:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.mmd.micro.common.TokenInterceptor">
<property name="excludeUrls">
<list>
<value>/app/token</value>
</list>
</property>
</bean>
</mvc:interceptor>
精彩评论