其他

Spring实现文件上传

必要前提

  1. form表单的 enctype取值必须是:multipart/form-data
  • 默认值是application/x-www-form-urlencoded
  • enctype是表单请求正文的类型
  1. method属性取值必须是 Post
  2. 提供一个文件选择域<input type="file" />

借助第三方组件实现文件上传

使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar

  • Commons-fileupload
  • commons-io

commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload组件从 1.1版本开始,它
工作时需要 commons-io包的支持。

文件上传回顾

  1. 导入jar
  2. 编写jsp
  3. 编写controller

  1. 导入jar
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
  1. 编写jsp
    <form action="user/fileupload" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload"/><br/>
        <input type="submit" value="上传文件"/>
    </form>
  1. 编写控制器
package com.bean.controller;


import com.bean.domain.User;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping(path = "/user")
public class HelloController {

    @RequestMapping(value = "/fileupload")
    public String sayHello(HttpServletRequest request) throws Exception {

        //因为上传的文件都解析到了request中,所以获取request

        //1. 获取到文件上传的目录,如果没有就创造一个
        String path = request.getSession().getServletContext().getRealPath("/uploads");
            //1.1 创建File对象,获取到文件路径
        File file = new File(path);
            //1. 判断此路径是否存在,不存在就创建
        if (!file.exists()){
            file.mkdirs();
        }

        //2. 创建磁盘文件项工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload fileUpload = new ServletFileUpload(factory);

        //3. 解析request对象
        List<FileItem> items = fileUpload.parseRequest(request);
            //3.1 遍历
        for (FileItem item : items) {
            if (item.isFormField()){
                //3.2 假如文件项是普通字段,那么不做处理
            }else {
                //3.2 假如文项是上传文件,那么上传文件
                    //3.2.1 获取到上传文件的名称
                String fileName = item.getName();
                    //3.2.2 给文件改个名字,避免重复覆盖,使用UUID,UUID生成的有-,替换为空字符串
                String replaceName = UUID.randomUUID().toString().replace("-", "");
                //3.2.3 上传文件
                item.write(new File(path,replaceName+"_"+fileName));
                //3.3 删除临时文件:文件大小小于10kb,则放到内存里,大于10kb,则会生成临时文件,所以清除临时文件
                item.delete();

            }
        }
        return "/success";
    }

}

SpringMVCTest\target\SpringMVCTest\uploads

放到了target包下


springMVC使用传统的方式上传

说明

注意在jsp中的上传文件的nameController中参数名字是相同的

配制文件解析器的时候,id必须为multipartResolver,这次这个不能随便改

实现步骤

  1. 配置文件解析器
  2. 编写jsp
  3. 编写Controller

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

    <!--这里开启注解扫描-->
    <context:component-scan base-package="com.bean"></context:component-scan>

    <!--配置视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--告诉前端控制器,什么内容不要拦截-->
    <mvc:resources location="/js/" mapping="/js/**"/>

    <!--配置文件解析器
        注意id必须叫做multipartResolver,这个不准配置
    -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--配置文件的最大值为10*1024*1024=10M-->
        <property name="maxUploadSize" value="10485760"/>
    </bean>


    <mvc:annotation-driven/>
</beans>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="js/jquery.min.js"></script>

</head>
<body>
    <h3>SpringMVC入门程序</h3>

    <form action="user/fileupload" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload"/><br/><%--注意,这里叫upload,那么Controller中的参数也叫upload--%>
        <input type="submit" value="上传文件"/>
    </form>

</body>
</html>

package com.bean.controller;


import com.bean.domain.User;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping(path = "/user")
public class HelloController {

    @RequestMapping(value = "/fileupload")
    public String sayHello(HttpServletRequest request, MultipartFile upload) throws Exception {

        //这里注意了,因为jsp中的name为upload,所以这里也应该是upload

        //获取到文件上传的目录,如果没有就创造一个
        String path = request.getSession().getServletContext().getRealPath("/uploads");
        File file = new File(path);
        if (!file.exists()){
            file.mkdirs();
        }

        //获取到上传文件的文件名称
        String name = upload.getOriginalFilename();
        //给文件名称唯一化
        String replaceName = UUID.randomUUID().toString().replace("-", "");

        //上传文件,不用做删除工作了,它做好了
        upload.transferTo(new File(path,replaceName+"_"+name));
        return "/success";
    }

}

springMVC跨服务器实现文件上传

在实际开发中,我们会有很多处理不同功能的服务器。例如:

  • 应用服务器:负责部署我们的应用
  • 数据库服务器:运行我们的数据库
  • 缓存和消息服务器:负责处理大并发访问的缓存和消息
  • 文件服务器:负责存储用户上传文件的服务器。

(注意:此处说的不是服务器集群)


  1. 准备两个 tomcat服务器,并创建一个用于存放图片的 web工程
  2. 拷贝 jar包(跨服务器开发的时候导入的jar包)
  3. 编写控制器实现上传图片
  4. 编写 jsp页面
  5. 配置解析器

注意了,新的tomcat在这里意味着新的项目,所以要加一个新的项目作为新的tomcat的运行


  • 准备存储图片的tomcat

还有一个最容易忘记的事情:建立上传文件夹,在这里我们建立uploads文件夹

target下面建立一个uploads

filesUpload\target\filesUpload\uploads


出错的原因:

  • 服务器报405:去tomcat下面找到:apache-tomcat-8.5.47\conf\web.xml
        <init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value>
        </init-param>
  • 服务器报404:原因是Controller本地路径没有没有进行关联起来,解决方法:把路径给idea托管

UploadsTest\target\UploadsTest\uploads

把这个文件放到tomcat服务器上进行托管

在配置第二个tomcat即配置存储图片服务器的时候,在idea下点开tomcat设置(就是配置路径的界面),手动在``Deployment中点击加号-->ExternalSource-->指定uploads`文件夹,点击ok,重新启动服务器


  • 拷贝jar
    <!--跨服务器上传的jarb包-->
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-core</artifactId>
      <version>1.18.1</version>
    </dependency>

    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-client</artifactId>
      <version>1.18.1</version>
    </dependency>

  • 编写jsp
  1. 发送的jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="js/jquery.min.js"></script>

</head>
<body>
    <h3>SpringMVC入门程序</h3>

    <form action="user/fileupload" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload"/><br/><%--注意,这里叫upload,那么Controller中的参数也叫upload--%>
        <input type="submit" value="上传文件"/>
    </form>

</body>
</html>
  1. 接受的jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>filesUpload</title>
</head>
<body>
    <h3>文件上传</h3>
</body>
</html>

  • 编写Controller
package com.bean.controller;


import com.bean.domain.User;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Controller
@RequestMapping(path = "/user")
public class HelloController {

    @RequestMapping(value = "/fileupload")
    public String sayHello( MultipartFile upload) throws Exception {

        //因为我们是跨服务器上传文件,所以我们就不需要Request了

        //1. 获取到上传文件的文件名称
        String name = upload.getOriginalFilename();
        //2. 给文件名称唯一化
        String replaceName = UUID.randomUUID().toString().replace("-", "")+"_"+name;
        //3. 上传文件,当然需要链接服务器
            //3.1 定义图片服务器的请求路径,因为我们启动的另一个服务器为:http://localhost:9090,并且要向文件夹uploads下传文件,所以这么定义
        String path = "http://localhost:9090/uploads/";
            //3.2 创建客户端对象
        Client client = Client.create();//注意导包import com.sun.jersey.api.client.Client;
            /*
            * 3.3 链接图片服务器,注意这里还有一个小细节,这里的总路径是:http://localhost:9090/uploads/文件名称
            * 其中"uploads/文件名称"中间的斜杠必须要有,要么在这里拼接,要么直接在path面前定义
            * */
        WebResource webResource = client.resource(path + replaceName);
        //3.4 上传文件,以字节形式上传
        webResource.put(upload.getBytes());
        return "/success";
    }

}

Spring异常处理

实现 HandlerExceptionResolver 接口

  1. 编写自定义异常类(做提示信息)和错误页面
  2. Controller中捕获异常,并抛出自己自定义的异常
  3. 编写异常处理器类
  4. 配置异常处理器(跳转到异常界面去)

  1. 编写异常类和错误页面
  • com.exception.SysException
package com.bean.exception;

public class SysException extends Exception {
    private String message;

    public SysException(String message) {
        this.message = message;
    }

    public SysException() {
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
  • exception.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Error</title>
</head>
<body>
    <h3>错误界面</h3>
    ${message}
</body>
</html>
  • index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="js/jquery.min.js"></script>

</head>
<body>
    <h3>SpringMVC入门程序</h3>

    <a href="user/hello">异常处理器</a>

</body>
</html>

  1. 捕获异常并抛出异常
package com.bean.controller;


import com.bean.exception.SysException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(path = "/user")
public class HelloController {

    @RequestMapping(value = "/hello")
    public String sayHello() throws SysException {

        try {
            int i = 1/0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new SysException("异常");
        }

        return "/success";
    }

}

  1. 编写异常处理器类(实现HanderExceptionResolver
package com.bean.exception;

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

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


public class SysExceptionResolver implements HandlerExceptionResolver {

    /**
     * 编写异常处理器
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e 捕获之后被抛出的异常
     * @return
     */
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {

        SysException exception = null;

        if (e instanceof SysException){
            exception = (SysException) e;
        }else {
            exception = new SysException("系统维护");
        }

        ModelAndView modelAndView = new ModelAndView();
        //获取到信息,存入request数据域中,message:exception.getMessage()
        modelAndView.addObject("message",exception.getMessage());
        //跳转到exception界面
        modelAndView.setViewName("/exception");

        return modelAndView;
    }
}

  1. 配置异常处理器(这个当作正常的bean对象配置就好了)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!--这里开启注解扫描-->
    <context:component-scan base-package="com.bean"></context:component-scan>

    <!--配置异常处理器-->
    <bean id="sysExceptionResolver" class="com.bean.exception.SysExceptionResolver"/>

    <!--配置视图解析器-->
    <bean id="exceptionResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--告诉前端控制器,什么内容不要拦截-->
    <mvc:resources location="/js/" mapping="/js/**"/>

    <!--配置文件解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760"/>
    </bean>

    <mvc:annotation-driven/>
</beans>

@ExceptionHandler注解

使用这个注解十分简单,我们只需要在需要的Controller里面的方法上面加入一个_@ExceptionHandler __ _注解即可

这个注解的值是你认为可能出现的异常,而使用这个注解之后的方法返回值也没有什么特别的要求,常见的ModelAndView,@ResponseBody,Entity都可

@Controller
@RequestMapping("/testController")
public class TestController {
 
    @RequestMapping("/demo1")
    @ResponseBody
    public Object demo1(){
        int i = 1 / 0;
        return new Date();
    }
 
    @ExceptionHandler({RuntimeException.class})
    public ModelAndView fix(Exception ex){
        System.out.println("do This");
        return new ModelAndView("error",new ModelMap("ex",ex.getMessage()));
    }
}

注意了,这个注解不是说写在你真正的Controller上面的,而是说在你这个Controller里面,只要匹配到了这个这种类型就会跳转到对应的方法里面去执行相关的代码

比如说上面这段代码,只要demo1里面报错了,而且是RuntimeExceotion类型的,那么就会跳转到fix方法里面去执行


@ControllerAdvice和@ExceptionHandler

刚才我们提到了@ExceptionHandler,确实非常方便,但是它只能在自己的Controller里面进行处理,那么就说明每一个Controller都要写一个

那么其实我们有更好的,就是@ControllerAdvice和@ExceptionHandler搭配,实现全局异常处理

@Controller
@RequestMapping("/testController")
public class TestController {
 
    @RequestMapping("/demo1")
    @ResponseBody
    public Object demo1(){
        int i = 1 / 0;
        return new Date();
    }
}
@ControllerAdvice
public class GlobalController {
 
    @ExceptionHandler(RuntimeException.class)
    public ModelAndView fix1(Exception e){
        System.out.println("全局的异常处理器");
        ModelMap mmp=new ModelMap();
        mmp.addAttribute("ex",e);
        return new ModelAndView("error",mmp);
    }
}

在这种情况下,我们的Controller和异常处理是分开的,就不必写到一起了

三种异常处理的比较

1、从优先级来讲

  • @Controller+@ExceptionHandler的优先级最高
  • @ControllerAdvice+@ExceptionHandler的优先级次之
  • HandlerResolver最低

注意,只要有一个异常已经处理了,那么其他两种方式就不会进行处理了

还有,假如一个条件同时满足了两个条件,比如同时满足了Exception和RuntimeException,而且这两种都是写在优先级相同的级别上(比如@ControllerAdvice+@ExceptionHandler),那么这个时候同样会满足一个异常已经处理,另一个异常就不会处理的情况

但是这种情况很有可能是我们不想看到的:比如我们想要走RuntimeException,但是实际上执行了Exception

所以针对这种情况我们可以进行处理,使用@Order注解即可,@Order注解是Spring中的注解,它定义了容器加载Bean的顺序,里面的值越小优先级越高,比如Order(-1)的优先级高于Order(0)

2、从返回类型上来讲

两个注解的方式其实都支持多种返回类型:ModelAndView,ResponseBody,Entity,…

但是基于接口的只能使用ModelAndView,假如你要想返回点别的,需要自己实现

3、缓存

@Controller和@ExceptionHandler的缓存信息在ExceptionHandlerExceptionResolver的exceptionHandlerCache

@ControllerAdvice和@ExceptionHandler的缓存信息在ExceptionHandlerExceptionResolver的exceptionHandlerAdviceCache

HandlerExceptionResolver接口不做缓存

在前面两种方式都fail的情况下才会走自己的HandlerExceptionResolver实现类,多少有点性能损耗

Spring拦截器


拦截器的处理时机

请求从前端控制器发入处理器映射器的过程中

拦截器和过滤器还是有些不同

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调

2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器

3、拦截器只能拦截请求(不能拦截静态资源),而过滤器则可以对几乎所有的请求起作用

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

7、过滤器在前端控制器之前执行,拦截器在前端控制器之后执行

实现拦截器

  1. 编写jsp
  2. 编写Controller
  3. 编写拦截器(实现HandlerInterceptor
  4. 配置拦截器

  1. 编写jsp
  • index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
        <script src="js/jquery.min.js"></script>

    </head>
    <body>
        <h3>SpringMVC入门程序</h3>

        <a href="user/hello">拦截器</a>

    </body>
</html>
  • success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%--注意这里isELIgnored="false",表示不忽略EL表达式--%>

<html>
    <head>
        <title>Title</title>
    </head>
    <body>

        <h3>跳转成功</h3>
        <%System.out.println("success.jsp页面跳转成功了");%>
    </body>
</html>

  1. 编写Controller
package com.bean.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(path = "/user")
public class HelloController {

    @RequestMapping(value = "/hello")
    public String sayHello(){
        return "/success";
    }

}

  1. 编写拦截器
  • 第一个拦截器
package com.bean.Interceptor;

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

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


/**
 * 这里是第一个拦截器
 * 在实现方法没有发现报错的时候不要慌,因为jdk1.8新特性允许接口自己实现
 * 要实现自己的功能还是要重写方法
 */
public class BeforeInterceptor implements HandlerInterceptor {

    /**
     * 在Controller之前执行
     * @param request
     * @param response
     * @param handler
     * @return  (true:放行,进入下一个拦截器或者Controller)
     * (false:不放行,可以利用request和response直接跳转错误界面)
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //可以跳转界面,但是别忘记返回false
        //request.getRequestDispatcher("/WEB-INF/pages/exception.jsp").forward(request,response);
        //return false;

        System.out.println("BeforeInterceptor中的preHandle方法执行了");
        return true;
    }

    /**
     * 在Controller之后执行,这个也可以利用request和response跳转界面
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //可以跳转界面
        //request.getRequestDispatcher("/WEB-INF/pages/exception.jsp").forward(request,response);

        System.out.println("BeforeInterceptor中的postHandle方法执行了");
    }


    /**
     * 在所有事情(包括跳转jsp)都做完之后执行
     * 所以注意了,既然所有的事情都做完了,在这里不能够跳转界面了
     * 也就是说,不可以在这里跳转界面
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("BeforeInterceptor中的afterCompletion方法执行了");
    }
}
  • 第二个拦截器
package com.bean.Interceptor;

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

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

/**
 * 这里是第二个拦截器
 */
public class AfterInterceptor implements HandlerInterceptor {

    /**
     * 在Controller之前执行
     * @param request
     * @param response
     * @param handler
     * @return  (true:放行,进入下一个拦截器或者Controller)
     * (false:不放行,可以利用request和response直接跳转错误界面)
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        System.out.println("AfterInterceptor中的preHandle方法执行了");

        return true;
    }

    /**
     * 在Controller之后执行,这个也可以利用request和response跳转界面
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("AfterInterceptor中的postHandle方法执行了");
    }


    /**
     * 在所有事情(包括跳转jsp)都做完之后执行
     * 所以注意了,既然所有的事情都做完了,在这里不能够跳转界面了
     * 也就是说,不可以在这里跳转界面
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("AfterInterceptor中的afterCompletion方法执行了");
    }
}

  1. 配置拦截器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!--这里开启注解扫描-->
    <context:component-scan base-package="com.bean"></context:component-scan>

    <!--配置拦截器们-->
    <mvc:interceptors>
        <!--配置第一个拦截器-->
        <mvc:interceptor>
            <!--配置要拦截的内容,这里配置的是访问user路径下的所有文件-->
            <mvc:mapping path="/user/*"/>
            <!--配置不要拦截的内容-->
            <!--<mvc:exclude-mapping path=""/>-->
            <!--配置拦截器,就像配置普通bean对象即可-->
            <bean id="beforeInterceptor" class="com.bean.Interceptor.BeforeInterceptor"/>
        </mvc:interceptor>

        <mvc:interceptor>
            <mvc:mapping path="/user/*"/>
            <!--<mvc:exclude-mapping path=""/>-->
            <bean id="" class="com.bean.Interceptor.AfterInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

    <!--配置视图解析器-->
    <bean id="exceptionResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--告诉前端控制器,什么内容不要拦截-->
    <mvc:resources location="/js/" mapping="/js/**"/>

    <!--配置文件解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760"/>
    </bean>

    <mvc:annotation-driven/>
</beans>

BeforeInterceptor中的preHandle方法执行了
AfterInterceptor中的preHandle方法执行了
AfterInterceptor中的postHandle方法执行了
BeforeInterceptor中的postHandle方法执行了
success.jsp页面跳转成功了
AfterInterceptor中的afterCompletion方法执行了
BeforeInterceptor中的afterCompletion方法执行了

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。