Filter和Interceptor的终归作用还是从入口修改或验证请求进来的数据
Filter是Java EE标准。Inteceptor是Spring 标准。
Filter在servlet前面,Interveptor在servlet之后
Filter和Inteceptor都可以改变httpservlet里面的数据内容,实现可以不用在Controoler层再去做验证的步骤,很美妙。
比如,去1除空白http参数的空白字符,2权限检验过滤,3设置http进出内容的编码格式,4对加解密参数进行加解密
5登陆状态验证。
Httpservlet 里面加入数据时候,是request.put(k,V)形式。所以可以猜想出来,request里面封装了hashmap接口,才能实现put key value。装饰者模式
但有个最扫兴的地方,Filter和Inteceptor的传入参数httpseretquest,已经被设置成不可修改里面的对象了,所以你只能读取httpservletreuest的内容,但不能修改httpservletrequest内容。这个是最悲催的一点,不过也可以理解,Java ee和spring想的就是传到业务层的数据是原始的真实的数据,不允许进行内容修改。
要想修改herpservletrequest入参对象,就要使用httpservletrequestwrapper类
javax.servlet.http.HttpServletRequestWrapper类来装饰HttpServletRequest对象。
httpservletrequest是java ee标准,
httpservletrequestwrapper也是java ee标准
修改httpservletrequest不可变对象最关键的精髓在于,通过hrttttpservletrequestwrapper来重写httpservletrequest的方法,对重写,也就是覆盖,修改其方法的返回值。这样就变相修改了啊httpservletrequest的修改,其实httpservletrequest
依然没被修改,也不能修改,我们只是生成了wrapper类样,这个类封装进httpservletrequest对象了
例如,Struts通过调用HttpServletRequest对象的getParameterValues()对象来处理action表单。通过覆盖装饰类中此方法,你可以改变当前HttpServletRequest对象的状态。
程序代码:
package trimmer.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class MyFilter implements Filter {
private FilterConfig filterConfig;
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter initialized");
this.filterConfig = filterConfig;
}
public void destroy() {
System.out.println("Filter destroyed");
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(new MyRequestWrapper((HttpServletRequest) request),
response);
}
}
小结
Servlet filter可以在调用一个servlet的服务方法后,拦载或加工HTTP请求。尽管这非常诱人,但其实际使用却有所限制,因为你不能改变HttpServletRequest对象。
这时候装饰模式派上了用场。本文演示了如何通过应用装饰模式来“修改”HttpServletRequest对象,从而使你的servlet filter更加有用。在上面filter例子中,filter改了request参数中的用户输入,而这一点,如果没有装饰request对象,你是无论如何也不可能做到的。
-----------------------------------------------------
package wrapper;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {
private String charset = "UTF-8";
public GetHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* 获得被装饰对象的引用和采用的字符编码
* @param request
* @param charset
*/
public GetHttpServletRequestWrapper(HttpServletRequest request,
String charset) {
super(request);
this.charset = charset;
}
/**
* 实际上就是调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换
*/
public String getParameter(String name) {
String value = super.getParameter(name);
value = value == null ? null : convert(value);
return value;
}
public String convert(String target) {
System.out.println("编码转换之前:" + target);
try {
return new String(target.trim().getBytes("ISO-8859-1"), charset);
} catch (UnsupportedEncodingException e) {
return target;
}
}
}
------------
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//设置请求响应字符编码
request.setCharacterEncoding(charset);
response.setCharacterEncoding(charset);
//新增加的代码
HttpServletRequest req = (HttpServletRequest)request;
if(req.getMethod().equalsIgnoreCase("get"))
{
req = new GetHttpServletRequestWrapper(req,charset);
}
System.out.println("----请求被"+config.getFilterName()+"过滤");
//传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象
chain.doFilter(req, response);
System.out.println("----响应被"+config.getFilterName()+"过滤");
2、继承HttpServletRequestWrapper 和HttpServletResponse 两个类对 getParameter(String str) 和getWrite()两方法进行重写,而方法中实现我们想要的操作
3、使用Filter过滤器,我们知道Filter是在请求到达servlet之前和servlet响应信息到达浏览器之前进行两次拦截,而就在到达server之前我们将FilterChain的doFilter(request,reponse)方法的request参数替换为我们装饰后的request而我们又重写的getParameter(String str)方法,之后调用的就是这个方法,因此也就完成了
请求参数的过滤和修改
4、响应和请求其实是一样的,也是替换了Response对象,从而调用我们重写的方法实
Filter和Interceptor的终归作用还是从入口修改或验证请求进来的数据的更多相关文章
- [转]web.xml中servlet ,filter ,listener ,interceptor的作用与区别
原文链接:https://blog.csdn.net/netdevgirl/article/details/51483273 一.概念: 1.servlet:servlet是一种运行服务器端的java ...
- servlet/filter/listener/interceptor区别与联系
转自:http://www.cnblogs.com/doit8791/p/4209442.html servlet.filter.listener是配置到web.xml中(web.xml 的加载顺序是 ...
- servlet & filter & listener & interceptor
web.xml 的加载顺序是:context- param -> listener -> filter -> servlet * Servlet 对URL生效,用户处理用户的URL请 ...
- 过滤器和拦截器filter和Interceptor的区别
1.创建一个Filter过滤器只需两个步骤 创建Filter处理类 web.xml文件中配置Filter 2.Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的 ...
- 【转】servlet/filter/listener/interceptor区别与联系
原文:https://www.cnblogs.com/doit8791/p/4209442.html 一.概念: 1.servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台 ...
- Java Web学习总结(29)——Java Web中的Filter和Interceptor比较
1. 背景 在设计web应用的时候,用户登录/注册是必不可少的功能,对用户登录信息进行验证的方法也是多种多样,大致可以认为如下模式:前端验证+后台验证.根据笔者的经验,一般会在前端进行一些例如是否输入 ...
- Filter,Interceptor和Aspect
过滤器使用的主要是反射 :拦截器使用的主要是回调 :AOP使用的主要是动态代理. 一个请求过来 ,先进行过滤器处理,看程序是否受理该请求.过滤器放过后, 程序中的拦截器进行处理,处理完后进入被AOP动 ...
- Spring 梳理 - filter、interceptor、aop实现与区别 -第二篇
spring mvc中的Interceptor可以理解为是Spring MVC框架对AOP的一种实现方式.一般简单的功能又是通用的,每个请求都要去处理的,比如判断token是否失效可以使用spring ...
- spring boot 拦截 以及Filter和interceptor 、Aspect区别
一.通过Filter这个大家很熟悉了吧,这是java规范的一个过滤器,他会拦截请求.在springboot中一般有两种配置方式.这种过滤器拦截并不知道你用的是哪一个Controller处理也不知道你用 ...
随机推荐
- webpack执行命令的不同方式
如使用webpack3及之前的版本只需安装webpack3即可,因为之前的webpack里面集成了webpack-cli 1. 使用局部安装webpack和webpack-cli,使用package. ...
- dbfread报错ValueError错误解决方法
问题 我在用dbfread处理.dbf数据的时候出现了报错 ValueError("could not convert string to float: b'.'",) 然后查找. ...
- Android自动化测试Uiautomator--UiDevice接口简介
Uiautomator主要分为UiDevice, UiObject, UiScrollable, UiSelector, UiCollection几个类. getUiDevice()方法可以得到一个U ...
- struts向网页输出图片验证码
前言:今天做个功能需要展示图片到页面,并不是下载,在网上搜了老半天,大部分都是下载,有的话也是只能在IE下进行输出,其它浏览器就都是下载了. Action代码: public String proce ...
- 分离焦虑OR责任焦虑
这里是用小孩上幼儿园的事说分离焦虑,转念到成人身上就是责任焦虑. 这周小孩开始上幼儿园了,他很害怕家长离开,我能做的也不多,只是很肯定的告诉他,爸爸就在停车场,下学就来接你,然后从各个 ...
- Matplotlib基本图形之折线图
Matplotlib基本图形之折线图折线图特点 折线图是用折线将各数据连起来组成的图形常用来观察数据随时间变化的趋势例如:股票价格,温度变化,等等 示例代码: import os import tim ...
- .NET重构(八):周结账单中,给报表添加参数
导读:进行完了日结报表的制作,大松一口气.不过,刚开始看着周结账单中的两个参数问题,也是愁了很久.不过,只要思想不滑坡,办法总比困难多.接下来,就写写我制作周结账单报表的过程. 一.添加参数 1,在日 ...
- 九度oj题目1008:最短路径问题
题目描述: 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. 输入: ...
- 原生 ajax get请求数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【Android】android:ellipsize的使用以及一个点解决方法
EidtText和textview中内容过长的话自动换行,使用android:ellipsize与android:singleine可以解决,使只有一行. EditText不支持marquee 用法如 ...