spring mvc 拦截器一次请求拦截两次?

问题描述

对于Spring mvc的拦截器我觉的应该是请求什么就该拦截什么,没有请求的就不该被拦截,但是不知道为什么,在如下的代码中,当我请求/路径的时候,我并没有请求index.html呀,为什么执行完控制器的代码和拦截器的postHandle方法之后,又执行了一次preHandle。我实在是想不明白为什么会是这样。详细内容如下:

相关代码

项目名称:codesound
Controller代码

    @RequestMapping(value="/",method=RequestMethod.GET)
    public String domain() {
        System.out.println("控制器被调用");
        return "index";    
    }

拦截器LoginInterceptor代码

package com.xy.codesound.interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("preHandle:"+request.getRequestURL());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
        
        
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion");
        
    }
    
}

拦截器配置信息

<?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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.3.xsd
          http://www.springframework.org/schema/mvc  http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 检查用户权限,对于部分不需要权限的路径进行排除 -->
        <mvc:interceptor>
            <!-- 先匹配所有路径,然后排除不需要检查的路径 -->
            <mvc:mapping path="/**" />
            <!-- 与登录相关的请求 -->
            <mvc:exclude-mapping path="/role"/>
            <mvc:exclude-mapping path="/login"/>
            <!-- 以下是静态资源 -->
            <mvc:exclude-mapping path="/resources/**" />
            <!--不知道为什么,拦截完controller之后controller返回的视图路径名,对应的html文件也会被拦截  -->
            <!-- 
            <mvc:exclude-mapping path="/WEB-INF/html/**" />
            -->
            <bean class="com.xy.codesound.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    
    <!-- 配置spring mvc -->
    <!-- 开启spring mvc注解模式 -->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!-- 不去拦截/resources/目录下的所有文件 -->
    <mvc:resources location="/resources/"
        mapping="/resources/**"></mvc:resources>
    <!-- <mvc:default-servlet-handler/>使用默认的servlet来相应静态文件, 因为在web.xml中使用了DispatcherServlet截获所有的请求url,而引入 
        <scprit type="text/javascript" src="js/jquery-1.11.0.mim.js"/> 的时候,DispatcherServlet会将“/”看成请求路径,找不到他的时候会报404错误。 
        而当配置文件加上这个默认的Servlet时,Servlet在找不到它时会去找静态内容,即js目录 -->
    <mvc:default-servlet-handler />
    <!-- 定义视图解析器 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/html/"></property>
        <property name="suffix" value=".html"></property>
    </bean>


    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 上传文件大小上限,单位为字节(10MB) -->
        <property name="maxUploadSize">
            <value>10485760</value>
        </property>
        <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
        <property name="defaultEncoding">
            <value>UTF-8</value>
        </property>
    </bean>

    <!-- 扫描web相关的bean -->
    <context:component-scan
        base-package="com.xy.codesound.web"></context:component-scan>
</beans>

当浏览器发起127.0.0.1:8080/codesound/请求,我期待的控制台输出结果是

preHandle:http://127.0.0.1:8080/codesound/
控制器被调用
postHandle
afterCompletion

实际看到的错误信息是

preHandle:http://127.0.0.1:8080/codesound/
控制器被调用
postHandle
preHandle:http://127.0.0.1:8080/codesound/WEB-INF/html/index.html
postHandle
afterCompletion
afterCompletion
阅读 5k
3 个回答

我感觉你的方法返回页面方式有问题,从拦截打印结果看好像走了相对路径,这不对啊

新手上路,请多包涵
 <mvc:exclude-mapping path="/WEB-INF/html/**" />被你注释了
 <!-- 
            <mvc:exclude-mapping path="/WEB-INF/html/**" />
            -->
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题