博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC拦截器
阅读量:5134 次
发布时间:2019-06-13

本文共 4030 字,大约阅读时间需要 13 分钟。

SpringMVC拦截器

什么是拦截器?

拦截器是指通过统一拦截从浏览器发往服务器的请求来完成功能的增强。通常用来处理请求中的共性问题。比如

  • 编码问题
  • 权限验证问题

可以减少重复代码,便于维护。

编写拦截器

自定义类实现HandlerInterceptor,并重写方法即可。

package com.shy.springmvcbingding.interceptor;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * @author Haiyu * @date 2018/10/9 13:25 */public class MyInterceptor implements HandlerInterceptor {    /**     *     * @param request request     * @param response response     * @param handler 被拦截的目标对象     * @return true表示被拦截后请求不会被终止;false表示被拦截后请求被终止     * @throws Exception     */    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        System.out.println("Pre");        System.out.println(handler.toString());        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {        System.out.println("post");        modelAndView.addObject("username", "被拦截并修改的用户名");        // 拦截原视图,直接替换成新视图//        modelAndView.setViewName("hello2");    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {        // 一般用来处理资源关闭等操作        System.out.println("after");    }}
  • preHandle:在请求被处理前进行调用
  • postHandle:在请求被处理后进行调用
  • afterCompletion:在请求结束之后才进行调用

preHandle方法的返回值如果是false,那么Controller中被拦截的方法以及postHandle、afterCompletion方法都不会执行。方法参数中,有两个参数需要提一下:

  • Object handler:指的是被拦截的目标对象,在这里就是被拦截的请求路径对应的方法;
  • ModelAndView modelAndView:通过该参数,可以改变被拦截请求的视图属性甚至替换视图。

然后在xml中配置拦截器,将我们定义的拦截器注入到Spring环境中。

<mvc:interceptor>标签中<mvc:mapping path="..."/>表示这个Interceptor只拦截该路径。如果不配置这个标签,将默认拦截所有路径。使用该标签可以使得针对不同的路径使用不同的拦截器。下面是路径请求路径为/hello的方法,根据上面的配置,MyInterceptor会拦截该请求。

@RequestMapping("/hello")public String hell0(Model model,                    @RequestParam("username") String username,                    @RequestParam("password") String password) {    System.out.println(username);    model.addAttribute("username", username);    model.addAttribute("password", password);    return "hello";}

再看hello视图,以jsp为例

<%@ page contentType="text/html;charset=UTF-8" %>    Title ${username} and ${password}

控制台打印

Prepublic java.lang.String com.shy.springmvcbingding.controller.JspController.hello(org.springframework.ui.Model,java.lang.String,java.lang.String)adminpostafter

jsp页面显示

被拦截并修改的用户名 and 1234

可以看到hello方法中打印的username还是admin,经postHandle拦截后,视图的username属性已经被修改了。

Spring Boot中配置拦截器

在Spring Boot中可以基于Java Config来注册拦截器,这样就可以抛弃xml配置了。我们只需自定义类实现WebMvcConfigurer,并重写addInterceptors方法即可,当然也可以重写addFormatters注册一个全局的Formatter用于转换日期。注意,该类要加上@Configuration注解,以便被Spring Boot扫描到并加载配置到上下文中。

package com.shy.springmvcbingding.config;import com.shy.springmvcbingding.interceptor.MyInterceptor;import org.springframework.context.annotation.Configuration;import org.springframework.format.FormatterRegistry;import org.springframework.format.datetime.DateFormatter;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/** * @author Haiyu * @date 2018/10/9 14:35 */@Configurationpublic class MyWebConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/hello");    }    /**     * 注册一个日期转换器     * @param registry     */    @Override    public void addFormatters(FormatterRegistry registry) {        registry.addFormatter(new DateFormatter());    }}

多个拦截器的执行顺序

看下图,如果配置的拦截器1在拦截器2之前,拦截顺序如下

Request -> 拦截器1 -> 拦截器2 -> SpringMVC控制器

Snipaste_2018-10-09_15-16-29

从图中可以看出:

  • preHandel:请求先被拦截器1拦截,然后被拦截器2拦截;
  • postHandle:请求先被拦截器2拦截,然后被拦截器1拦截;
  • afterCompletion:请求先被拦截器2拦截,然后被拦截器1拦截。

by @sunhaiyu

2018.10.9

转载于:https://www.cnblogs.com/sun-haiyu/p/9760794.html

你可能感兴趣的文章
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
nginx 不带www到www域名的重定向
查看>>
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>
Java Servlet 过滤器与 springmvc 拦截器的区别?
查看>>
(tmp >> 8) & 0xff;
查看>>
linux命令之ifconfig详细解释
查看>>
NAT地址转换
查看>>
Nhibernate 过长的字符串报错 dehydration property
查看>>
Deque - leetcode 【双端队列】
查看>>
gulp插件gulp-ruby-sass和livereload插件
查看>>
免费的大数据学习资料,这一份就足够
查看>>
clientWidth、clientHeight、offsetWidth、offsetHeight以及scrollWidth、scrollHeight
查看>>