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高级应用的更多相关文章

  1. Filter高级开发

    孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(四十三)——Filter高级开发 在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以 ...

  2. javaweb学习总结(四十三)——Filter高级开发

    在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...

  3. javaweb学习总结——Filter高级开发

    在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...

  4. Servlet Filter 3

    11.MD5加密 /** * 使用md5的算法进行加密 */ public static String md5(String plainText) { byte[] secretBytes = nul ...

  5. 15.Filter(过滤器)

    1.管理所有WEB资源:(Jsp, Servlet, 静态图片文件或静态 html 文件等)文件等进行拦截,从而实现一些特殊的功能 2.Filter接口中有一个doFilter方法,当我们编写好Fil ...

  6. 【JavaWeb学习】过滤器Filter

    一.简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静 ...

  7. django 操作数据库--orm(object relation mapping)---models

    思想 django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM). PHP:activerecord Java:Hibernate C#:Ent ...

  8. 如何使用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; ...

  9. JavaWeb学习总结(转载)

    JavaWeb学习总结(五十三)--Web应用中使用JavaMail发送邮件      JavaWeb学习总结(五十二)--使用JavaMail创建邮件和发送邮件     JavaWeb学习总结(五十 ...

随机推荐

  1. Android 开源项目android-open-project解析之(三) ScrollView,TimeView,TipView,FlipView

    九.ScrollView Discrollview 支持滚动时Item淡入淡出,平移,缩放效果的ScrollView 项目地址:https://github.com/flavienlaurent/di ...

  2. RabbitMQ和kafka从几个角度简单的对比--转

    业界对于消息的传递有多种方案和产品,本文就比较有代表性的两个MQ(rabbitMQ,kafka)进行阐述和做简单的对比, 在应用场景方面, RabbitMQ,遵循AMQP协议,由内在高并发的erlan ...

  3. svcutil 生成代理类时的问题

    如果有这个的xsd, group内嵌choice的结构: <xs:complexType name="CreateType">        <xs:sequen ...

  4. JSON 遍历转为Model Bean

    @RequestMapping(value = "/batchAddPageIndexBrand") @ResponseBody public HashMap<String, ...

  5. Django初探--开发环境搭建(笔记)

    1. Django框架的安装 (1) 下载Django源码 Django-1.7.11.tar.gz,并解压,网址:https://www.djangoproject.com/download/ (2 ...

  6. Set Keep-Alive Values---C到C#代码的转换

    一.什么是Keep-Alive模式? 我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成 之后立即断开连接(HT ...

  7. 016_openxml_forxml

    016_openxml_forxml --openxml*********************************************************************** ...

  8. UIGestureRecognizer手势识别

    UIGestureRecognizer 1.#import "ViewController.h"2.3.@interface ViewController ()<UIGest ...

  9. Swift - 12 - 区间运算符和for-in

    //: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...

  10. PHP PDO 简单登陆操作

    用PHP做出一个简单的登陆操作,确实很简单,下面就让我给大家简单的介绍一下PDO做出一个登陆界面操作的过程,因为也是初学乍练,不足之处请大家包涵. 首先,首先还要建一个表,在MySQL中建表,核心代码 ...