javaweb 中的过滤器 包装器

过滤器要做的事情:

请求过滤器:完毕安全检查,又一次格式化请求首部或体。建立请求审计或日志

响应过滤器:

压缩响应流,追加或改动响应流创建一个全然不同的响应.

过滤器和servlet三个相似地方:

1.容器知道过滤器的api,过滤器api的其他成员能够訪问ServletContext 还能够与其他过滤器链接

2.容器管理过滤器的生命周期,过滤器有init和destroy方法。还有doFilter方法

3.web应用能够有非常多过滤器。须要在配置文件里配置

过滤器的生命周期

init 容器实例化一个过滤器时。在init方法中完毕调用过滤器之前全部的初始化任务。

保存filterConfig对象

的一个引用,以备过滤去以后使用.

其次调用 doFIlter 能够保存username记录到一个文件里,压缩响应输出。

最后destroy删除一个过滤器实例,

FilterChain的doFIlter 方法要负责明白接下来调用谁的doFilter放大,假设到达链尾,则要确定调用哪个servlet的service方法。

在配置文件里确定过滤器的顺序

在配置文件里做三件事

1.声明过滤器

2.将过滤器映射到你想过滤的web资源

3,组织这些映射,创建过滤器调用序列

声明过滤器

<filter>

<filter-name>BeerRequest</filter-name>

<filter-class>com.gac.test.BeerRequestFilter</filter-class>

<init-param>

<param-name>LogFileName</param-name>

<param-value>UserLog.txt</param-value>

</init-param>

</filter>

声明url模式的过滤器映射

<filter-mapping>

<filter-name>BeerRequest</filter-name>

<url-pattern>*.do</url-pattern>

</filter-mapping>

声明相应servlet名的过滤器映射

<filter-mapping>

<filter-name>BeerRequest</filter-name>

<servlet-name>AdviceServlet</servlet-name>

</filter-mapping>

为通过请求分派请求的web资源声明一个过滤器映射

<filter-mapping>

<filter-name>MonitorFilter</filter-name>

<url-pattern>*.do</url-pattern>

<dispatcher>REQUEST</dispatcher>

和/或

<dispatcher>INCLUDE</dispatcher>

和/或

<dispatcher>FORWARD</dispatcher>

和/或

<dispatcher>ERRO</dispatcher>

</filter-mapping>

声明规则:

必需要有filter-name

必需要有url-pattern或servlet-name元素当中之中的一个

能够有0-4个dispatcher

Request值表示对client请求启用过滤器,假设没有指定<dispatcher>元素。则默觉得

Rquest

INCLUDE值表示对由一个include()调用分派来的请求启用过滤器

FORWARD值表示对一个由forward()调用分派来的请求启用过滤器

ERROR值表示对错误处理调用资源启用过滤器

过滤器请求路径样例

<filter-mapping>

<filter-name>Filter1</filter-name>

<url-pattern>/Recipes/*<url-pattern>       /Recipes/HopsReport.do 过滤器序列 1 5

</filter-mapping>                  /Recipes/HopsList.do 过滤器 15 2

<filter-mapping>

<filter-name>Filter2</filter-name>          /Recipes/Modify/ModRecipes.do 过滤器 1 5 4

<url-pattern>/Recipes/HopsList.do<url-pattern>  /HopsList.do 过滤器 5

</filter-mapping>

<filter-mapping>                                         /Recipes/Add/AddRecipes.do 过滤器 1 3 5

<filter-name>Filter3</filter-name>

<url-pattern>/Recipes/Add/*<url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>Filter4</filter-name>

<url-pattern>/Recipes/Modify/ModRecipes.do<url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>Filter5</filter-name>

<url-pattern>/*<url-pattern>

</filter-mapping>

/**************************************************************/

//过滤器必须实现Filter接口

public class BeerRequestFilter implements Filter{

private FilterConfig fc;

//完毕清理工作

@Override

public void destroy() {

// TODO Auto-generated method stub

}

//详细的业务逻辑

@Override

public void doFilter(ServletRequest req, ServletResponse resp,

FilterChain chain) throws IOException, ServletException {

// TODO Auto-generated method stub

HttpServletRequest httpReq = (HttpServletRequest) req;//能够将请求和响应对象强制转换为Http类型

String name = httpReq.getRemoteUser();

if(name != null){

fc.getServletContext().log("User"+name +"is updating");

}

chain.doFilter(req, resp);//接下来要调用的过滤器或者servlet

}

//必须实现init 通常只在当中保存配置config对象

@Override

public void init(FilterConfig config) throws ServletException {

// TODO Auto-generated method stub

this.fc = config;

}

}

/***************************************************************/

为过滤器压缩数据响应为了不实现太多的函数降低复杂性能够利用包装器。

利用包装器的演示样例

public class CompressFilter implements Filter{

private ServletContext ctx;

private FilterConfig cfg;

@Override

public void destroy() {

// TODO Auto-generated method stub

cfg = null;

ctx = null;

}

//这个过滤器核心是用装饰包装响应对象,他用一个压缩的IO流包装输出流.

//当且仅当客户包括一个Accept-Encoding首部 才会完毕输出流压缩

@Override

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

// TODO Auto-generated method stub

HttpServletRequest req = (HttpServletRequest)request;

HttpServletResponse resp  =(HttpServletResponse) response;

String valid_encodings = req.getHeader("Accept-Encoding");//客户是否接收gzip压缩

if( valid_encodings.indexOf("gzip") > -1 ){

ComPressResponseWrapper wrappedResp = new ComPressResponseWrapper(resp);

wrappedResp.setHeader("Content-Encoding","gzip");

chain.doFilter(req, wrappedResp);

GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream();

gzos.finish();

ctx.log(cfg.getFilterName()+": finished the request. ");

}else{

ctx.log(cfg.getFilterName()+": no encoding performed.");

}

}

//init方法保存配置对象,并保存servlet上下文对象的一个直接引用 以便完毕日志记录

@Override

public void init(FilterConfig filterConfig) throws ServletException {

// TODO Auto-generated method stub

this.cfg = filterConfig;

ctx = cfg.getServletContext();

ctx.log(cfg.getFilterName()+" initialized.");

}

}

public class ComPressResponseWrapper extends HttpServletResponseWrapper{

private GZIPServletOutputStream servletGzipOS = null;//servlet响应的压缩输出流

private PrintWriter pw = null;

public ComPressResponseWrapper(HttpServletResponse response) {

super(response);

// TODO Auto-generated constructor stub

}

public void setContentLength(int len){}

/*过滤器使用这个装饰器的方法压缩过滤器提供一个GZIP输出流的句柄,以便过滤器完毕和刷新输出GZIP流*/

public GZIPOutputStream getGZIPOutputStream(){

return this.servletGzipOS.internalGzipOS;

}

private Object streamUsed = null;//同意訪问所装饰的servlet输出流

public ServletOutputStream getOutputStream()throws IOException{

//仅当servlet还没有訪问打印书写器时 同意servlet訪问servlet输出流

if((null != streamUsed) && (streamUsed!=pw)){

throw new IllegalStateException();

}

//用我们的压缩输出流包装原来的servlet输出流

if(servletGzipOS == null){

servletGzipOS =

new GZIPServletOutputStream(getResponse().getOutputStream());

streamUsed = servletGzipOS;

}

return servletGzipOS;

}

//执行訪问所装饰的打印书写器

public PrintWriter getWriter() throws IOException{

if((streamUsed != null) && (streamUsed != servletGzipOS)){

throw new IllegalStateException();

}

if(pw == null){

servletGzipOS =

new GZIPServletOutputStream(getResponse().getOutputStream());

OutputStreamWriter osw =

new OutputStreamWriter(servletGzipOS,getResponse().getCharacterEncoding());

pw = new PrintWriter(osw);

streamUsed = pw;

}

return pw;

}

}

class GZIPServletOutputStream extends ServletOutputStream{

/*internalGzipOs保存对原始Gzip流的一个引用。这个实例变量在包范围内私有,所以响应包装器能够訪问这个变量*/

GZIPOutputStream internalGzipOS;

//装饰器构造函数

GZIPServletOutputStream(ServletOutputStream sos) throws IOException{

this.internalGzipOS = new GZIPOutputStream(sos);

}

//这种方法把write调用托付给GZIP压缩流 从而实现压缩装饰 GZIP压缩流包装了原来的ServletOutputStream

@Override

public void write(int b) throws IOException {

// TODO Auto-generated method stub

internalGzipOS.write(b);

}

}

时间: 2024-10-12 09:10:16

javaweb 中的过滤器 包装器的相关文章

asp.net core 2.2 中的过滤器/筛选器(上)

ASP.NET Core中的过滤器/筛选器 通过使用 ASP.NET Core MVC 中的筛选器,可在请求处理管道中的特定阶段之前或之后运行代码. 注意:本主题不适用于 Razor 页面. ASP.NET Core 2.1 及更高版本支持适用于 Razor 页面的 IPageFilter 和 IAsyncPageFilter. 有关详细信息,请参阅 Razor 页面的筛选方法. 内置筛选器处理一些任务,例如: 授权(防止用户访问未获授权的资源). 确保所有请求都使用 HTTPS. 响应缓存(对

Java 中的 Characters 包装器类型

1.一般情况下,如果使用单一的 character 值,应该使用原始的 char 类型.比如: public class TestCharacter { public static void main(String[] args) { char ch = 'a'; char uniChar = '\u03A9'; char[] charArray = {'a','b','c'}; System.out.println("ch:" + ch + " uniChar:"

过滤器与包装器

过滤器允许你拦截请求,也允许你控制响应.Filter很像Servlet,容器管理过滤器的生命周期.和Servlet类似,过滤器也有init()和destroy()方法,对应于servlet的doGet()/doPost(),过滤器则有一个doFilter()方法.过滤器也需要在DD中声明,过滤器的运行顺序也将在DD中声明. 1.过滤器中的生命周期 首先要有一个inti(),最常见的实现是在inti()中保存一个FilterConfig的引用,以备过滤器以后使用(获取过滤器参数等). 真正的工作在

【Head First Servlets and JSP】笔记 28: 过滤器与包装器

1.过滤器的执行顺序: <url-pattern> 为第一梯队, <servlet-name> 为第二梯队,梯队内的执行顺序和 DD 里的声明顺序相同. When the container recives a request, it first finds all the filter mappings with a <url-pattern> that matches the request URI. This becomes the first set of fi

Java中的StringBuffer、StringBuilder和包装器类型

1.如何使用StringBuffer类? 答:1).StringBuffer类用于表示可以修改的字符串,称为字符串缓冲对象: 2).使用运算符的字符串将自动创建字符串缓冲对象: 例:str1 + str2的操作,实际上把str1与str2都创建成StringBuffer类对象: 2.StringBuffer类的构造方法有哪些常用的重载方式? 答:StringBuffer()        创建一个空的StringBuffer对象,默认保留16个字符的缓冲空间 StringBuffer(Strin

javaweb中的servlet相关知识

class01 javaweb基础 一.OSI参考模型: 应用层.表示层.会话层 传输层. 网络层. 数据链路层. 物理层一共七层 二.与OSI参考模型对应的TCP/IP四层模型: 应用层. 传输层. 网际层. 网络接口层 三.http协议的主要特点: 遵循请求/响应模型 无连接:每次连接只处理一个请求 处理完请求后就释放连接 无状态:http协议对于事物处理没有记忆能力 即每次连接互不影响 灵活:可以传输任意类型数据对象 简单快捷:客户端向服务器发送请求时,只需要传送请求和路径 四.http协

JavaWeb chapter 8 过滤器

1.  一个中间组件,用于拦截源数据和目的数据之间的消息,过滤二者之间传递的数据: 2.  Servlet过滤器是驻留在Web服务器上的Web组件,过滤从客户端传递到服务器端的请求和相应. 3.  多个过滤器可以组成一个过滤器链,链中的每个过滤器负责特定的操作和任务,客户端的请求和相应在这些过滤器之间传递. 4.  过滤器的一些常见应用: 认证过滤:对用户请求进行统一的认证: 登录和审核过滤:对用户的访问请求进行记录和审核: 图像转换过滤:转换图像格式: 数据压缩过滤:对用户发送的数据进行压缩,

《Head First Servlets & JSP》-13-过滤器和包装器

过滤器是什么 与servlet非常类似,过滤器就是java组件,请求发送到servlet之前,可以用过滤器截获和处理清求,另外 servlet结束工作之后,在响应发回给客户之前,可以用过滤器处理响应. 容器根据DD中的声明来确定何时调用过滤器.在DD中,部署人员要建映射.明确对于哪个请求URL模式要调用哪些过滤器.所以,要由部署人员(而不是程序员)来确定哪些请求或响应应当由哪些过滤器处理. 过滤器要做的事情 只有一个过滤器接口:Filter,根据使用方式,可完成诸如以下工作: 请求过滤器可以完成

Spring Boot项目中如何定制拦截器

本文首发于个人网站:Spring Boot项目中如何定制拦截器 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供HandlerInterceptor(拦截器)工具.根据文档,HandlerInterceptor的功能跟过滤器类似,但拦截器提供更精细的控制能力:在request被响应之前.request被响应之后.视图渲染之前以及request全部结束之后.我们不能通过拦截器修改request内容,但是可以通过抛出异