拦截器与过滤器的区别

spring的拦截器与servlet的filter有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查、日志记录等,不同的是:

  • 适用范围不同:filter是servlet规范规定的,只能用于web程序中;而拦截器既可用于web程序,也可用于application、swing程序中。
  • 规范不同:filter是servlet规范定义的,是servlet容器支持的,而拦截器是spring容器中的,是spring框架支持的。
  • 使用资源不同:同其他代码块一样,拦截器也是一个spring组件,归spring管理,配置在spring文件中,因此能使用spring里的任何资源、对象,例如service对象、数据源事务管理等,通过IOC注入到拦截器即可。而filter则不能。
  • 深度不同:Filter只能在servlet前后起作用。而拦截器能够深入到方法前后,异常抛出前后等,因此拦截器具有更大的弹性,在spring框架的程序中,优先使用拦截器。

最简单明了的区别就是

  • 过滤器可以修改request,而拦截器不能
  • 过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境
  • 拦截器可以调用IOC容器中的各种依赖,而过滤器不能
  • 过滤器只能在请求的前后使用,而拦截器可以详细到每个方法

拦截器的使用

拦截器(Interceptor)和过滤器不同(filter),但是也可以实现方法前中后的处理策略,一般情况是进入方法前进行拦截,然后进行身份验证。下面是实现进入方法前的身份,这里是使用groovy写的,与java略有差异
1、实现拦截器

@Component
@Slf4j
class SecurityInterceptor implements HandlerInterceptor {String account_interface_url@Value('${account_interface_url}')void setAccount_interface_url(String account_interface_url) {this.account_interface_url = account_interface_url}//Controller逻辑执行之前@Overrideboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {def name,ticketresponse.setCharacterEncoding("UTF-8")if(!request.getHeader("ticket")){JSONObject json = new JSONObject()json.put("code","1")json.put("msg","认证失败,无访问权限")response.getWriter().write(json.toString())return false}ticket = request.getHeader("ticket").toString()if(handler instanceof HandlerMethod){name = handler.getMethod().getName().toString()}def url = String.format(account_interface_url,ticket,"test111")println name//这里是远程调用权限接口def account = Http.http_request(url)println accountJSONObject account_result = new JSONObject(account)if(account_result.has("status")&& account_result.getString("status") == "NOT_FOUND"){JSONObject json = new JSONObject()json.put("code","1")json.put("msg","认证失败,无访问权限")response.getWriter().write(json.toString())return false}return true}//Controller逻辑执行完毕但是视图解析器还未进行解析之前@Overridevoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}//Controller逻辑和视图解析器执行完毕@Overridevoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}

2、注册拦截器
实现拦截器后需要将拦截器注册到spring容器中,可以通过implements WebMvcConfigurer覆盖addInterceptor方法,把Bean注册到Spring容器中,可以选择@Component 或者 @Configuration。

@Configuration
class SecurityConfigurer implements WebMvcConfigurer{@BeanSecurityInterceptor securityInterceptor(){return new SecurityInterceptor()}@Overridevoid addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(securityInterceptor()).addPathPatterns("/**").excludePathPatterns("/*.html")}
}

相信很多人对preHandle方法中的HttpServletReques, HttpServletResponse , handler这三个类的功能比较模糊,所以在这里进行简单的介绍。
3、HttpServletRequest
web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的response对象。他们分别代表着请求和响应,如果需要客户端提交过来的数据,只需要request对象就可以,如果要向客户端发送信息,就需要response对象。
HttpServletRequest代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。
获得客户端信息:

方法 说明
getRequestURL() 返回客户端发出请求时的完整URL。
getRequestURI() 返回请求行中的参数部分。
getQueryString () 方法返回请求行中的参数部分(参数名+值)
getRemoteHost() 返回发出请求的客户机的完整主机名。
getRemoteAddr() 返回发出请求的客户机的IP地址。
getPathInfo() 返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以"/"开头。
getRemotePort() 返回客户机所使用的网络端口号。
getLocalAddr() 返回WEB服务器的IP地址。
getLocalName() 返回WEB服务器的主机名。

获取客户端请求头

方法 说明
getHeader(string name) 以 String 的形式返回指定请求头的值。如果该请求不包含指定名称的头,则此方法返回 null。如果有多个具有相同名称的头,则此方法返回请求中的第一个头。头名称是不区分大小写的。可以将此方法与任何请求头一起使用
getHeaders(String name) 以 String 对象的 Enumeration 的形式返回指定请求头的所有值
getHeaderNames() 返回此请求包含的所有头名称的枚举。如果该请求没有头,则此方法返回一个空枚举

获得客户机请求参数

方法 说明
getParameter(String name) 根据name获取请求参数(常用)
getParameterValues(String name) 根据name获取请求参数列表(常用)
getParameterMap() 返回的是一个Map类型的值,该返回值记录着前端(如jsp页面)所提交请求中的请求参数和请求参数值的映射关系。(编写框架时常用)

4、HttpServletResponse
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。
response对象的功能分为以下四种:

  • 设置响应头信息
  • 发送状态码
  • 设置响应正文
  • 重定向
    4.1 设置响应头信息
方法 说明
addHeader(String name, String value) 添加具有给定名称和值的响应标头。此方法允许响应标头具有多个值。
addDateHeader(String name, long date) 添加具有给定名称和日期值的响应标头。 日期以自纪元以来的毫秒数指定。 此方法允许响应标头具有多个值
addIntHeader(String name, int value) 添加具有给定名称和整数值的响应标头。 此方法允许响应标头具有多个值
containsHeader(String name) 返回一个布尔值,指示是否已设置命名的响应标头
setHeader 同add方法
setDateHeader 同add方法
setIntHeader 同add方法

4.2 设置状态码

方法 说明
setStatus(int sc) 设置此响应的状态代码。 此方法用于设置没有错误时的返回状态码(例如,对于状态码 SC_OK 或 SC_MOVED_TEMPORARILY)。 如果出现错误,并且调用者希望调用 Web 应用程序中定义的错误页面,则应改用 sendError 方法
setStatus(int sc, String sm) 设置此响应的状态代码和消息

常用的状态码

Name discribtion 释义
200 SC_OK 此次请求已经成功
301 SC_MOVED_PERMANENTLY 请求的网页已永久移动到新位置
302 SC_MOVED_TEMPORARILY 临时移动、请求地址不变
401 SC_UNAUTHORIZED 未授权、用户需登录
403 SC_FORBIDDEN 服务器拒绝了此次请求(权限问题)
404 SC_NOT_FOUND 服务器没找到URI匹配的
405 SC_METHOD_NOT_ALLOWED 调用的方法不允许使用(get、post不匹配)
500 SC_INTERNAL_SERVER_ERROR 服务器内部发生异常,请求中断
502 SC_BAD_GATEWAY 网关错误(如Nginx),无法收到服务器的响应
504 SC_GATEWAY_TIMEOUT 请求超时,在约定时间内没有收到Http响应

4.3 发送响应正文
4.3.1 使用OutputStream流输出中文
这段是参考javaweb学习总结(七)——HttpServletResponse对象(一)是java代码。

     String data = "中国";OutputStream outputStream = response.getOutputStream();//获取OutputStream输出流response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码/*** data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表,* 如果是中文的操作系统环境,默认就是查找查GB2312的码表,* 将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字* 比如: "中"在GB2312的码表上对应的数字是98*         "国"在GB2312的码表上对应的数字是99*//*** getBytes()方法如果不带参数,那么就会根据操作系统的语言环境来选择转换码表,如果是中文操作系统,那么就使用GB2312的码表*/byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组

4.3.2 使用PrintWriter流向客户端浏览器输出中文数据

//将字符以"UTF-8"编码输出到客户端浏览器
response.setCharacterEncoding("UTF-8")
//获取输出流,写入数据
response.getWriter().write("hello world")

4.4 重定向
重定向的方法

response.setHeader("Location", "http://www.itcast.cn");
response.sendRedirect("http://www.itcast.cn");

5、HandlerMethod
Spring MVC应用启动时会搜集并分析每个Web控制器方法,从中提取对应的"<请求匹配条件,控制器方法>“映射关系,形成一个映射关系表保存在一个RequestMappingHandlerMapping bean中。然后在客户请求到达时,再使用RequestMappingHandlerMapping中的该映射关系表找到相应的控制器方法去处理该请求。在RequestMappingHandlerMapping中保存的每个”<请求匹配条件,控制器方法>"映射关系对儿中,"请求匹配条件"通过RequestMappingInfo包装和表示,而"控制器方法"则通过HandlerMethod来包装和表示。
一个HandlerMethod对象,可以认为是对如下信息的一个包装 :

信息名称 介绍
Object bean Web控制器方法所在的Web控制器bean。可以是字符串,代表bean的名称;也可以是bean实例对象本身
Class beanType Web控制器方法所在的Web控制器bean的类型,如果该bean被代理,这里记录的是被代理的用户类信息
Method method Web控制器方法
Method bridgedMethod 被桥接的Web控制器方法
MethodParameter[] parameters Web控制器方法的参数信息:所在类所在方法,参数,索引,参数类型
HttpStatus responseStatus 注解@ResponseStatus的code属性
String responseStatusReason 注解@ResponseStatus的reason属性

下面,是HandlerMethodn属性字段的源码

public class HandlerMethod {// 虽然Object类型,但是注册handlerMethod时候构造的时候有可能传入的是一个String类型的bean nameprivate final Object bean;// 见名知义,我调试的时候,传入的是DefaultListableBeanFactory,如果bean属性是Sring的beanName就可以用beanName获取到对应的bean作用Handlerprivate final BeanFactory beanFactory;// 方法所属类private final Class<?> beanType;// 注册的方法private final Method method;// 被桥接的方法,如果method是原生的,这个属性的值就是methodprivate final Method bridgedMethod;// 封装方法参数的类实例,一个MethodParameter就是一个参数private final MethodParameter[] parameters;// Http状态码private HttpStatus responseStatus;// ResponseStatus注解的reason值private String responseStatusReason;private HandlerMethod resolvedFromHandlerMethod;//...

springboot拦截器和过滤器的区别与使用相关推荐

  1. 详解拦截器和过滤器的区别

    拦截器和过滤器的区别 过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对acti ...

  2. SpringBoot 拦截器和过滤器

    拦截器和过滤器 时光飞逝,最近也是很忙,但是忙到最后发现在自己并没有太多的成长 工作 学习 生活 没想到成长是不经意间的,像是被 推着,让你身不由己 午休时间,写写博客,也是保留一些自己的时间和空间 ...

  3. java 拦截器和过滤器的区别

    介绍 在 Java Web 应用程序中,拦截器和过滤器是两种不同的机制,用于在请求/响应处理过程中进行拦截和过滤.两者都可以用来在请求到达目标资源之前对其进行预处理.修改或拦截. 但是,拦截器和过滤器 ...

  4. 拦截器和过滤器的区别 -- 简单分析篇

    过滤器,是在Java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法u ...

  5. 大剑无锋之拦截器和过滤器的区别【面试推荐】

    ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求 ...

  6. 区分Java拦截器和过滤器

    今天带大家分析java拦截器和过滤器的区别,文中有非常详细的解释说明,对正在学习java的小伙伴们有很好的帮助,需要的朋友可以参考下 一.过滤器(filter) 过滤器处于客户端与Web资源(Serv ...

  7. struts2中拦截器和过滤器的比较

    拦截器和过滤器的区别: 1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而 ...

  8. 【SpringMVC】拦截器和过滤器

    拦截器: 拦截器是springmvc中的一种,需要实现HandlerInterceptor接口. 拦截器和过滤器类似,功能方向侧重点不同. 过滤器是用来过滤器请求参数,设置编码字符集等工作. 拦截器是 ...

  9. 关于SSM框架设置拦截器和过滤器

    我们知道拦截器和过滤器都是在项目中起到拦截过滤请求的功能,所以可能在设置的时候会傻傻分不清.这里我们先来比较它们的区别. 过滤器Filter是JavaEE标准,在Servlet的规范中定义的,是Ser ...

最新文章

  1. web存储中cookie、session区别
  2. leetcode算法题--Letter Case Permutation
  3. STM32mini使用UCOSII信号量和邮箱实现任务挂起和恢复
  4. Spring MyBatis多数据源分包
  5. iNeuOS工业互联网操作系统,顺利从NetCore3.1升级到Net6的过程汇报,发布3.7版本...
  6. link 和 style 元素在 HTML 文档中的位置
  7. python控制结构是,python 程序控制结构
  8. android toast 带图片,Android 带图片的Toast
  9. 虚幻竞技场3中的配置文件
  10. java.lang.IllegalArgumentException: Malformed \uxxxx encoding
  11. 移动硬盘损坏如何恢复数据
  12. mac os 直接打开html文件,macos – 在Mac OS X上打开磁盘设备文件以进行写访问
  13. 罗杨美慧 20190905-1 每周例行报告
  14. 【pandas之DataFrame相关函数】loc()函数、iloc函数
  15. 人工智能快速发展,目前的人工智能处于什么阶段?
  16. java获取时间的各种风格_各种获取时间的方法包含各类时间格式
  17. pve7 安装rhel9.0报错之Fatal glibc error: CPU does not support x86-64-v2处理及Kernel panic - not syncing
  18. Tensorflow-slim 做扑克,麻将,花牌的分类
  19. STM32输出互补死区刹车PWM
  20. vue+node---使用element框架实现的前后台用户登录注册功能

热门文章

  1. 全链路压测:构建三大模型
  2. css实现图片全屏铺满自适应的三种方法
  3. jquery用ajax提交表单
  4. matlab基础知识:行向量产生、访问及绘图
  5. C#纯技术——Class写入Json
  6. 如何利用canvas画一个圆,并且填充颜色
  7. 在线进销存软件免费版,哪个可以用?
  8. ZZULIOJ:1008: 美元和人民币
  9. 等价类划分法与边界值分析法
  10. fis2 入门--fis3使用