【问题标题】:Spring interceptor is not getting invokedSpring拦截器没有被调用
【发布时间】:2016-04-14 16:57:27
【问题描述】:

我开始使用 spring 拦截器,并想简单地记录每个请求的调用时间。

我的拦截器类:

package com.ankit.notice.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class ExecuteTimeInterceptor extends HandlerInterceptorAdapter{

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {

        long startTime = System.currentTimeMillis();
        System.out.println("Time is " + startTime);
        return true;
    }
}

root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/context                http://www.springframework.org/schema/context/spring-context-3.0.xsd  
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!-- Root Context: defines shared resources visible to all other web components -->

<context:component-scan base-package="com.ankit.notice" />
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:interceptors>
    <bean class="com.ankit.notice.interceptor.ExecuteTimeInterceptor" />
</mvc:interceptors> 

   .....
</beans>

控制器类

    @RequestMapping(value = "api/getAllItems.rest", method =     RequestMethod.GET)  
    public ResponseEntity<Map<String, Object>> getAllItems(
        HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        ResponseEntity<Map<String, Object>> responseEntity = null;
        Map<String, Object> responseParams = new HashMap<String, Object>();

        try {
            User user = (User) session.getAttribute("user");
            if ((null == user) || (user.getId() < 0)) {
                throw new MNPSessionException(
                        "INVALID USER : Session attribute user is not set correctly");
            }
         ....
     }  

我没有控制器类的请求映射,而是将请求直接映射到方法。 (我知道这是一种不好的做法,但我正在努力:))

web.xml

        <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  


http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>

<context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>  
<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>*.json</url-pattern>
</servlet-mapping>
    <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>*.rest</url-pattern>
</servlet-mapping>  

 <filter>
    <filter-name>sessionCheckFilter</filter-name>
    <filter-class>com.ankit.notice.util.SessionCheckFilter</filter-class>
</filter>  

filter-mapping>
<filter-name>sessionCheckFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>  
</web-app>

请求网址 localhost:8080/mvc/api/getAllItems.rest

根据我的理解,由于mvc:interceptors 标签中没有提供映射,所以应该为所有请求调用拦截器。

在我的控制台中,没有可用的 sysout 输出。我尝试返回 false 以确保拦截器和 sysout 没有问题,但无济于事。

另外,我尝试删除删除 mvc:annotation-driven 标记,但没有调用拦截器。

任何指针这里可能有什么问题?还有其他选项,例如创建 BeanNameUrlHandlerMapping 类的 bean 和使用属性:listmapping 创建 RequestMappingHandlerMapping 类的 bean,但它们都不起作用。有人能指出这些方法之间的区别,并指出何时使用哪种方法吗?

【问题讨论】:

  • 你在测试什么请求 url。提供控制器类和web.xml以及应用配置

标签: java spring spring-mvc interceptor


【解决方案1】:

为了“覆盖”拦截器,我使用了注释的配置类@Configuration(在“config”包中创建)。

无需使用任何 xml 配置。

package com.abc.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.abc.interceptor.BaseInterceptor;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BaseInterceptor());
    }

}

【讨论】:

    【解决方案2】:

    我发誓你已经忘记了“mvc:interceptor”标签中的“mvc:interceptor”标签:

    您可以尝试以下方法吗?

    <mvc:interceptors>
      
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean  id="executeTimeInterceptor"  class="com.ankit.notice.interceptor.ExecuteTimeInterceptor" />
        </mvc:interceptor>
      
    </mvc:interceptors>

    【讨论】:

    • 我在发布问题之前尝试过同样的方法,但没有成功。
    • 抱歉再次询问,但是您是否尝试在 bean 拦截器定义中包含 mvc:mapping path="/**" ?另一个问题:您可以尝试仅使用弹簧上下文进行更简单的测试吗?您同时拥有 root-context.xml 和 servlet-context.xml .... 可能您可以尝试只使用一个 servlet-context.xml 并将您的 bean 拦截器移到那里 ...
    • 是的,我试过了,没用。另外,当您说 servlet-context.xml 时,您是指 web.xml 吗?如果是,那么根据 spring 文档,拦截器应在应用程序上下文中定义,即此处的 root-context.xml。请参考spring docs advisory
    • 您好,请问您是否找到了使用弹簧拦截器的解决方案。我在 GitHub 中编写了一个类似的 Spring MVC 应用程序,并且 spring 拦截器对我来说工作正常。如果您想将其与您的代码进行比较,我将与您分享 GitHub 链接:https://github.com/PabloEzequiel/Java/tree/master/myApiRest 在我的示例中,我还尝试了您代码中的一些片段,这些都工作正常,所以我找不到代码中的错误在哪里您已在此问题中复制,因为您的代码在矿井中运行正常
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多