正确的 mvc:Spring 中的拦截器配置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5656124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 04:25:45  来源:igfitidea点击:

Proper mvc:interceptor configuration in Spring

springinterceptor

提问by rinzler

I have kind of a problem. I need to call on each request postHandle method in this interceptor:

我有点问题。我需要在这个拦截器中调用每个请求 postHandle 方法:

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.

所以我将此行放入 servlet 配置中,一切正常。

<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>

但是现在我必须更改配置并使用 <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.

使用此配置,我在 postHandle 方法中的 modelAndView 上收到一系列空指针异常,因为每个请求多次调用 postHandle 方法。

 <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.

使用此配置,它可以工作,但仅适用于请求 serverAdress/任何东西。对于请求 serverAdress/anything/something 是 postHandle 未调用。

<mvc:interceptors>
   <mvc:interceptor>
     <mvc:mapping path="/*" />
     <bean class="cz.cosi.DiMenuInterceptor" />
   </mvc:interceptor>
</mvc:interceptors>

part of servlet configuration

servlet 配置的一部分

<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.

看来,问题可能以某种方式与资源有关,因为除了没有正确加载的图像、样式和 javascript。没有 mvc:resources 它可以正常工作,但这不是解决方案。

My question is, how to properly configure DiMenuInterceptor with <mvc:interceptors>. Thanks very much for the advices.

我的问题是,如何正确配置 DiMenuInterceptor 与<mvc:interceptors>. 非常感谢您的建议。

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 java.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>

回答by Ralph

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

@see Excample in Spring Reference, Chapter 15.12.2 mvc:interceptors

回答by Craig Swing

The problem is that the interceptors are called when resources are requested.

问题是在请求资源时调用拦截器。

This posttalks 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.

这篇文章讨论了如何防止使用 xml 配置调用拦截器。在接受的答案中,我不太喜欢依赖路径的语义构成(即使用 .html 或在路径中包含页面)。现在,团队中的所有开发人员在创建控制器时都必须意识到这一点。

I also am not a fan of the verbose bean configuration, so I have decided to add the following code to the interceptor:

我也不喜欢冗长的 bean 配置,所以我决定在拦截器中添加以下代码:

if (ClassUtils.isAssignableValue(ResourceHttpRequestHandler.class, handler)) {
    return;
}

// do interceptor logic here...

回答by mariusz117

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:

我遇到了非常相似的问题,但是访问 Bootstrap 3 的字体。拦截器阻止了诸如“glyphicons-halflings-regular.woff”或“glyphicons-halflings-regular.ttf”之类的字体资源,并且它们在首页中不可见。我通过以下方式解决了我的问题。我的拦截器的定义如下所示:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cz.cosi.DiMenuInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

And my DiMenuInterceptor class:

还有我的 DiMenuInterceptor 类:

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;
    }
}

回答by Richard Xue

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:mapping”,它起作用了。我的新配置如下:

<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>