web-dev-qa-db-ja.com

Springでの適切なmvc: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());
   }
}

だから私はサーブレット構成にこの行を入れて、すべてがうまくいきます。

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:interceptors-ref="menuInterceptor" />

<bean id="menuInterceptor" class="cz.cosi.DiMenuInterceptor" />

しかし、今は設定を変更して<mvc:interceptors>を使用する必要があります

この構成では、postHandleメソッドがリクエストごとに複数回呼び出されるため、postHandleメソッドのmodelAndViewで一連のnullポインター例外が発生します。

 <mvc:interceptors>
    <bean class="cz.cosi.DiMenuInterceptor" />
 </mvc:interceptors>

この構成では機能しますが、要求serverAdress/anythingに対してのみです。リクエストの場合、serverAdress/anything/somethingはpostHandleが呼び出されていません。

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

サーブレット構成の一部

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

例外は適切に読み込まれた画像、スタイル、JavaScriptでないため、問題はリソースに何らかの形で関係しているようです。 mvc:resourcesがないと正しく機能しますが、これは解決策ではありません。

私の質問は、<mvc:interceptors>を使用してDiMenuInterceptorを適切に構成する方法です。アドバイスありがとうございます。

スタック:

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)

多分私は解決策を見つけましたが、それは間違いなく最高ではありません。今のところ、それは機能しているようです。

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

パスにサブパスが含まれていることを指定する必要があります:/**"代わりに/*

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

@スプリングリファレンスの例を参照 第15.12.2章mvc:interceptors

15
Ralph

問題は、リソースが要求されたときにインターセプターが呼び出されることです。

この post は、xml構成を使用してインターセプターが呼び出されないようにする方法について説明しています。受け入れられた答えでは、私はパスのセマンティック構成(つまり、.htmlを使用するか、パスにページを含める)に依存することはあまり好きではありません。これで、チームのすべての開発者は、コントローラーを作成するときにこれを認識する必要があります。

また、私は冗長Bean構成のファンではないため、次のコードをインターセプターに追加することにしました。

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

// do interceptor logic here...
1
Craig Swing

私も同じ質問をしました。初期構成:

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

「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>
0
Richard Xue

私は非常によく似た問題を抱えていましたが、Bootstrap 3.のフォントにアクセスすることでした。フロントページに表示されない次の方法で問題を解決します。インターセプターの定義は次のようになります。

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

そして私の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;
    }
}
0
mariusz117