filter高级应用
Filter高级应用:
Decorator模式
1)包装类需要和被包装对象 实现相同接口,或者继承相同父类
2)包装类需要持有 被包装对象的引用
在包装类中定义成员变量,通过包装类构造方法,传入被包装对象
3)在包装类中,可以控制原来那些方法需要加强
不需要加强 ,调用被包装对象的方法
需要加强,编写增强代码逻辑
ServletRequestWrapper 和 HttpServletRequestWrapper
提供对request对象进行包装的方法,但是默认情况下每个方法都是调用原来request对象的方法,
也就是说包装类并没有对request进行增强
如果要增强就可以在这两个包装类基础上,继承HttpServletRequestWrapper 和 HttpServletRequestWrapper 覆盖需要增强的方法即可
6.完全解决get和post乱码的过滤器
在Filter中,对request对象进行包装,增强获得参数的方法
getParameter
getParameterValues
getParameterMap
参考代码:
public class GenericEncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 转型为与协议相关对象
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 对request包装增强
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
// 自定义request对象
class MyRequest extends HttpServletRequestWrapper { private HttpServletRequest request; private boolean hasEncode; public MyRequest(HttpServletRequest request) {
super(request);// super必须写
this.request = request;
}
// 对需要增强方法 进行覆盖
@Override
public Map getParameterMap() {
// 先获得请求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
// post请求
try {
// 处理post乱码
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
// get请求
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) { // 确保get手动编码逻辑只运行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
// 处理get乱码
values[i] = new String(values[i]
.getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回参数的第一个值
}
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
增强Response对象,对响应数据进行压缩
先说一下在Tomcat服务器内,提供对响应压缩 配置实现
在conf/server.xml 中
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"/> 添加 compressableMimeType="text/html,text/xml,text/plain" compression="on"
public class GzipFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 自定义缓冲区,重写response的getWriter和getOutputStream
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// 字节缓存区
// 将数据写入内存数组中
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
HttpServletResponse myresponse = new HttpServletResponseWrapper(
httpServletResponse) {
private PrintWriter out;
@Override
// 重写getWriter 流获得是对 getOutputStream 编码获得
public PrintWriter getWriter() throws IOException {
System.out.println("getWriter...");
if (out == null) {
// 确保PrintWriter只有一个对象,flushbuffer中输出缓冲区内容
out = new PrintWriter(new OutputStreamWriter(
byteArrayOutputStream, getCharacterEncoding()));
}
return out;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
System.out.println("getOutputStream...");
return new ServletOutputStream() {
@Override
// 将数据写到哪
public void write(int b) throws IOException {
// 将响应数据 写入自定义缓存区
byteArrayOutputStream.write(b);
}
};
}
@Override
public void flushBuffer() throws IOException {
getOutputStream().flush();
getWriter().flush();
}
};
// 目标资源执行,只有目标资源执行后,才有响应数据
chain.doFilter(request, myresponse);
myresponse.flushBuffer();
// 目标资源已经执行过,数据已经在 byteArrayOutputStream 缓存区
byte[] data = byteArrayOutputStream.toByteArray(); // data是未压缩数据
System.out.println("未压缩数据长度:" + data.length);
// 读data数据进行压缩
byte[] gzipData = gzip(data);// gzipData是压缩后数据
System.out.println("压缩后数据长度:" + gzipData.length);
// 原来response 目的地是客户端浏览器
httpServletResponse.setHeader("Content-Encoding", "gzip");
httpServletResponse.setContentLength(gzipData.length);
httpServletResponse.getOutputStream().write(gzipData);
httpServletResponse.getOutputStream().flush();
}
// 对data数据进行gzip压缩
public byte[] gzip(byte[] data) {
// 定义字节缓存区,用gzip方式向缓存区写数据
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
try {
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(
arrayOutputStream);
gzipOutputStream.write(data);// 将原数据 压缩gzip格式写入新的缓存区\
gzipOutputStream.close();
arrayOutputStream.flush();
return arrayOutputStream.toByteArray();// 返回压缩后的内容
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("压缩失败!");
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
天下代码一般仿写:http://blog.csdn.net/javadaddy/article/details/8142559
filter高级应用的更多相关文章
- Filter高级开发
孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(四十三)——Filter高级开发 在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以 ...
- javaweb学习总结(四十三)——Filter高级开发
在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...
- javaweb学习总结——Filter高级开发
在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...
- Servlet Filter 3
11.MD5加密 /** * 使用md5的算法进行加密 */ public static String md5(String plainText) { byte[] secretBytes = nul ...
- 15.Filter(过滤器)
1.管理所有WEB资源:(Jsp, Servlet, 静态图片文件或静态 html 文件等)文件等进行拦截,从而实现一些特殊的功能 2.Filter接口中有一个doFilter方法,当我们编写好Fil ...
- 【JavaWeb学习】过滤器Filter
一.简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静 ...
- django 操作数据库--orm(object relation mapping)---models
思想 django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM). PHP:activerecord Java:Hibernate C#:Ent ...
- 如何使用ASP.NET Web API OData在Oracle中使用Entity Framework 6.x Code-First方式开发 OData V4 Service
环境: Visual Studio 2013 + .Net Framework 4.5.2 1.新建项目 2.安装OData,ODP.NET 安装的包: 下面是部分代码: using System; ...
- JavaWeb学习总结(转载)
JavaWeb学习总结(五十三)--Web应用中使用JavaMail发送邮件 JavaWeb学习总结(五十二)--使用JavaMail创建邮件和发送邮件 JavaWeb学习总结(五十 ...
随机推荐
- TeleMCU视频会议之Android版本号WebRTC client支持
本文原创自 http://blog.csdn.net/voipmaker 转载注明出处. 最新版本号TeleMCU 添加了Android手机端WebRTC视频会议能力,Android手机安装Chro ...
- [转] Maven镜像配置
参考:许晓斌的<Maven实战> 镜像是为了提供更快的服务 如图:X就认为是Y的一个镜像. 编辑settings.xml配置中央仓库镜像: <settings> ... < ...
- NYOJ128前缀式计算
前缀式计算 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 先说明一下什么是中缀式: 如2+(3+4)*5这种我们最常见的式子就是中缀式. 而把中缀式按运算顺序加上括 ...
- 堆和栈 内存分配 heap stack
Java中的堆和栈 在[函数]中定义的一些[基本类型的变量]和[对象的引用变量]都是在函数的[栈内存]中分配的.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间, ...
- codevs 1994 排队 排列组合+高精度
/* 数学题0.0 最后答案:A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*C(m,1)*A(2,2)*C(n+1,1)*A(n+2,m-1); 简单解释一下 +之前的很显然 先排男 ...
- BestCoder 1st Anniversary
Souvenir Accepts: 1078 Submissions: 2366 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 26 ...
- My.Ioc 代码示例——Lifetime 和 ILifetimeScope
很多 Ioc 框架在创建对象的过程中,都会采取某种方式来缓存/复用/释放已构建的对象.在 My.Ioc 中,这个目的是通过 Lifetime/ILifetimeScope 来实现的.其中,Lifeti ...
- dedecms 使noflag参数及其过滤多个属性的修改方法
noflag='h' 是代表不包含头条属性的意思,其中flag就是属性, 自定义属性值:头条[h]推荐[c]图片[p]幻灯[f]滚动[s]跳转[j]图文[a]加粗[b]. noflag过滤多个属性的修 ...
- 【javascript模式】Chapter2: 基本 技巧
1 尽量少用全局变量,最好一个应用程式只有一个全局变量 隐含全局变量(不使用var声明)与明确定义的全局变量区别: (1)使用var创建的全局变量(在函数外部声明)不能用delete删除 (2) ...
- leetcode修炼之路——383. Ransom Note
题目是这样的 Given an arbitrary ransom note string and another string containing letters from a ...