Spring filter的用法

[b]Spring filter的用法[/b]

1.Filter技术是servlet 2.3新增加的功能。它能够对Servlet容器的请求和响应对象进行检查和修改。
2.过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
3.Filter本身并不生成请求和响应对象,只是提供过滤功能。
4.Filter能够在Servlet被调用之前检查Request对象,并修改Request Header和Request内容;在Servlet被调用之后检查Response对象,修改Response Header和Response的内容。
5.所有的过滤器都必须实现Filter接口
6.web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter


[b]Filter的执行流程:[/b]
1.执行第一个过滤器的chain.doFilter()之前的代码-->
2.第二个过滤器的chain.doFilter()之前的代码-->……-->第n个过滤器的chain.doFilter()之前的代码-->
3.所请求servlet的service()方法中的代码-->所请求servlet的doGet()或doPost()方法中的代码-->
4.第n个过滤器的chain.doFilter()之后的代码-->……-->
5.第二个过滤器的chain.doFilter()之后的代码-->第一个过滤器的chain.doFilter()之后的代码。


[b]Filter生命周期的四个阶段[/b]
(1)实例化:Web容器在部署Web应用程序时对所有过滤器进行实例化。Web容器回调它的无参构造方法。
(2)初始化:实例化完成之后,马上进行初始化工作。Web容器回调init()方法。
(3)过滤:请求路径匹配过滤器的URL映射时。Web容器回调doFilter()方法--主要的工作方法。
(4)销毁: Web容器在卸载Web应用程序前,Web容器回调destroy()方法。


[b]例子:[/b]
1.编写java类实现Filter接口,并实现其doFilter方法。
public class FilterTest implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
String username = filterConfig.getInitParameter("username");
System.out.println("init username == " + username);

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 转换成实例的请求和响应对象
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;

System.out.println("doFilter before");
chain.doFilter(req, resp);
System.out.println("doFilter after");
}

@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("FilterTest destroy == ");
}
}



2.在web. xml中配置过滤器(多个filter就是多个复制)
<filter>
<filter-name>filterTest</filter-name>
<filter-class>com.proserver.common.controller.Test.filter.FilterTest</filter-class>
<init-param>
<param-name>userName</param-name>
<param-value>HelloWorld</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>filterTest</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>filterTest3</filter-name>
<filter-class>com.proserver.common.controller.Test.filter.FilterTest3</filter-class>
<init-param>
<param-name>userName</param-name>
<param-value>HelloWorld</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>filterTest3</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>filterTest2</filter-name>
<filter-class>com.proserver.common.controller.Test.filter.FilterTest2</filter-class>
<init-param>
<param-name>userName</param-name>
<param-value>HelloWorld</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>filterTest2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>



1.filter定义过滤器的类
2.filter-mapping定义过滤器的的匹配规则(url-pattern匹配规则)
3.init-param为配置参数,可从FilterConfig中得到
4.servlet-name指定过滤器所拦截的Servlet名称。(过滤器规则),<servlet-name>元素给出的Servlet名字必须是 在<servlet>元素中声明过的Servlet的名字。
5.url-pattern指定过滤器规则,正则表达式。加了/表示绝对路径http://localhost:8080/ ,没有加 / 表示的是相对路径
6.dispatcher指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。(就是请求的来源)
(1)REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
(2)INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
(3)FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
(4)ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。


[b]HttpServletRequestWrapper、HttpServletResponseWrapper,HttpSessionWrapper 用法[/b]
1.用于filter操作请求和回应包信息的

[b]例子:[/b]
package com.proserver.common.controller.Test.filter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class WrapperedResponse extends HttpServletResponseWrapper {

private ByteArrayOutputStream buffer = null;
private ServletOutputStream out = null;
private PrintWriter writer = null;

public WrapperedResponse(HttpServletResponse resp) throws IOException {
super(resp);
buffer = new ByteArrayOutputStream();// 真正存储数据的流
out = new WapperedOutputStream(buffer);
writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding()));
}

/** 重载父类获取outputstream的方法 */
@Override
public ServletOutputStream getOutputStream() throws IOException {
return out;
}

/** 重载父类获取writer的方法 */
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException {
return writer;
}

/** 重载父类获取flushBuffer的方法 */
@Override
public void flushBuffer() throws IOException {
if (out != null) {
out.flush();
}
if (writer != null) {
writer.flush();
}
}

@Override
public void reset() {
buffer.reset();
}

/** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */
public byte[] getResponseData() throws IOException {
flushBuffer();
return buffer.toByteArray();
}

/** 内部类,对ServletOutputStream进行包装 */
private class WapperedOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos = null;

public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
bos = stream;
}

@Override
public void write(int b) throws IOException {
bos.write(b);
}

@Override
public void write(byte[] b) throws IOException {
bos.write(b, 0, b.length);
}
}
}


package com.proserver.common.controller.Test.filter;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class ResponseWrapper extends HttpServletResponseWrapper{
private PrintWriter cachedWriter;
private CharArrayWriter bufferedWriter;

public ResponseWrapper(HttpServletResponse response) {
super(response);
// 这个是我们保存返回结果的地方
bufferedWriter = new CharArrayWriter();
// 这个是包装PrintWriter的,让所有结果通过这个PrintWriter写入到bufferedWriter中
cachedWriter = new PrintWriter(bufferedWriter);
}

@Override
public PrintWriter getWriter() {
return cachedWriter;
}

/**
* 获取原始的HTML页面内容。
* @return
*/
public String getResult() {
return bufferedWriter.toString();
}
}



package com.proserver.common.controller.Test.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FilterTest2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String username = filterConfig.getInitParameter("username");
System.out.println("FilterTest2 init username == " + username);

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 转换成实例的请求和响应对象
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;

System.out.println("begin filter invoke!");
WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse)response);

chain.doFilter(req, wrapResponse);
byte[] data = wrapResponse.getResponseData();
System.out.println("原始数据: " + new String(data));

String tempData = new String("jack xing xing");
ServletOutputStream out = resp.getOutputStream();
resp.setContentLength(tempData.getBytes().length);//一定要更改长度
out.write(tempData.getBytes());
out.flush();
System.out.println("end filter invoke!");
}

@Override
public void destroy() {
System.out.println("FilterTest2 FilterTest destroy == ");
}
}


[url]http://zhangzhaoaaa.iteye.com/blog/1853787[/url]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值