过滤器Filter也具有生命周期:init()->doFilter()->destroy(),由部署文件中的filter元素驱动。在servlet2.4中,过滤器同样可以用于请求分派器,但须在web.xml中声明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>该元素位于filter-mapping中。
一、批量设置请求编码
Java代码
- publicclassEncodingFilterimplementsFilter{
-
- privateStringencoding=null;
-
- publicvoiddestroy(){
- encoding=null;
- }
-
- publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,
- FilterChainchain)throwsIOException,ServletException{
- Stringencoding=getEncoding();
- if(encoding==null){
- encoding="gb2312";
- }
- request.setCharacterEncoding(encoding);//在请求里设置上指定的编码
- chain.doFilter(request,response);
- }
-
- publicvoidinit(FilterConfigfilterConfig)throwsServletException{
- this.encoding=filterConfig.getInitParameter("encoding");
- }
-
- privateStringgetEncoding(){
- returnthis.encoding;
- }
-
- }
Xml代码
- <filter>
- <filter-name>EncodingFilter</filter-name>
- <filter-class>com.logcd.filter.EncodingFilter</filter-class>
- <init-param>
- <param-name>encoding</param-name>
- <param-value>gb2312</param-value>
- </init-param>
- </filter>
-
- <filter-mapping>
- <filter-name>EncodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
二、用filter控制用户访问权限
Java代码
- publicvoiddoFilter(ServletRequestrequest,
- ServletResponseresponse,
- FilterChainchain)
- throwsIOException,ServletException{
-
- HttpServletRequestreq=(HttpServletRequest)request;
- HttpServletResponseres=(HttpServletResponse)response;
-
- HttpSessionsession=req.getSession();
- if(session.getAttribute("username")!=null){//登录后才能访问
- chain.doFilter(request,response);
- }else{
- res.sendRedirect("../failure.jsp");
- }
- }
Xml代码
- <filter>
- <filter-name>SecurityFilter</filter-name>
- <filter-class>com.logcd.filter.SecurityFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>SecurityFilter</filter-name>
- <url-pattern>/admin/*</url-pattern>
- </filter-mapping>
三、过滤链
两个过滤器,EncodingFilter负责设置编码,SecurityFilter负责控制权限,服务器会按照web.xml中过滤器定义的先后循序组装成一条链,然后一次执行其中的doFilter()方法。执行的顺序就如上图所示,执行第一个过滤器的chain.doFilter()之前的代码,第二个过滤器的chain.doFilter()之前的代码,请求的资源,第二个过滤器的chain.doFilter()之后的代码,第一个过滤器的chain.doFilter()之后的代码,最后返回响应。
执行的代码顺序是:
- 执行EncodingFilter.doFilter()中chain.doFilter()之前的部分:request.setCharacterEncoding("gb2312");
- 执行SecurityFilter.doFilter()中chain.doFilter()之前的部分:判断用户是否已登录。
- 如果用户已登录,则访问请求的资源:/admin/index.jsp。
- 如果用户未登录,则页面重定向到:/failure.jsp。
- 执行SecurityFilter.doFilter()中chain.doFilter()之后的部分:这里没有代码。
- 执行EncodingFilter.doFilter()中chain.doFilter()之后的部分:这里也没有代码。
过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题,像EncodingFilter就一定要放在所有Filter之前,这样才能确保在使用请求中的数据前设置正确的编码。
四、使用filter,结合gzip 压缩技术,解决web应用中网络传输数据量大的问题
gzip是http协议中使用的一种加密算法,客户端向web服务器端发出了请求后,通常情况下服务器端会将页面文件和其他资源,返回到客户端,客户端加载后渲染呈现,这种情况文件一般都比较大,如果开启Gzip ,那么服务器端响应后,会将页面,JS,CSS等文本文件或者其他文件通过高压缩算法将其压缩,然后传输到客户端,由客户端的浏览器负责解压缩与呈现。通常能节省40%以上的流量(一般都有60%左右),一些PHP,JSP文件也能够进行压缩。
1.Tomcat 直接开启Gzip
打开Tomcat 目录下的conf下的server.xml,并找到如下信息:
Xml代码
- <!--Note:Tousegzipcompressionyoucouldsetthefollowingproperties:
- compression="on"
- compressionMinSize="2048"
- noCompressionUserAgents="gozilla,traviata"
- compressableMimeType="text/html,text/xml"
- -->
把它们加入到你配置的<Connector port="80" .../>中去。如果要压缩css 和 js,加入compressableMimeType="text/html,text/xml,text/css,text/javascript"。还要压缩图片,加入compressableMimeType="text/html,text/xml,text/css,text/javascript,image/gif,image/jpg"。
开启后重启Tomcat ,通过浏览器查看headers信息就能看到是否开启。
2.使用filter,在代码级别完成web应用的gzip压缩的开启。
(1).CachedResponseWrapper类
实现定制输出的关键是对HttpServletResponse 进行包装,截获所有的输出,等到过滤器链处理完毕后,再对截获的输出进行处理,并写入到真正的HttpServletResponse 对象中。JavaEE 框架已经定义了一个HttpServletResponseWrapper 类使得包装HttpServletResponse 更加容易。我们扩展这个HttpServletResponseWrapper,截获所有的输出,并保存到ByteArrayOutputStream 中。
定制的包装响应能方便地从帮助类 HttpServletResponseWrapper 中导出。这一类粗略地执行许多方法,允许我们简单地覆盖 getOutputStream() 方法以及 getWriter() 方法,提供了定制输出流的实例。
HttpServletResponseWrapper这个类的使用包括以下五个步骤:
1)建立一个响应包装器。扩展javax.servlet.http.HttpServletResponseWrapper。
2)提供一个缓存输出的PrintWriter。重载getWriter方法,返回一个保存发送给它的所有东西的PrintWriter,并把结果存进一个可以稍后访问的字段中。
3)传递该包装器给doFilter。此调用是合法的,因为HttpServletResponseWrapper实现HttpServletResponse。
4)提取和修改输出。在调用FilterChain的doFilter方法后,原资源的输出只要利用步骤2中提供的机制就可以得到。只要对你的应用适合,就可以修改或替换它。
5)发送修改过的输出到客户机。因为原资源不再发送输出到客户机(这些输出已经存放到你的响应包装器中了),所以必须发送这些输出。这样,你的过滤器需要从原响应对象中获得PrintWriter或OutputStream,并传递修改过的输出到该流中。
Java代码
- /**
- *Wrapper:在内存中开辟一个ByteOutputStream,然后将拦截的响应写入byte[],
- *写入完毕后,再将wrapper的byte[]写入真正的response对象
- *Thisclassisusedforwrappedresponseforgettingcacheddata.
- */
- classCachedResponseWrapperextendsHttpServletResponseWrapper{
-
- /**
- *IndicatethatgetOutputStream()orgetWriter()isnotcalledyet.
- */
- publicstaticfinalintOUTPUT_NONE=0;
-
- /**
- *IndicatethatgetWriter()isalreadycalled.
- */
- publicstaticfinalintOUTPUT_WRITER=1;
-
- /**
- *IndicatethatgetOutputStream()isalreadycalled.
- */
- publicstaticfinalintOUTPUT_STREAM=2;
-
- privateintoutputType=OUTPUT_NONE;
-
- privateintstatus=SC_OK;
-
- privateServletOutputStreamoutput=null;
-
- privatePrintWriterwriter=null;
-
- privateByteArrayOutputStreambuffer=null;
-
- publicCachedResponseWrapper(HttpServletResponseresp)throwsIOException{
- super(resp);
- buffer=newByteArrayOutputStream();
- }
-
- publicintgetStatus(){
- returnstatus;
- }
-
- publicvoidsetStatus(intstatus){
- super.setStatus(status);
- this.status=status;
- }
-
- publicvoidsetStatus(intstatus,Stringstring){
- super.setStatus(status,string);
- this.status=status;
- }
-
- publicvoidsendError(intstatus,Stringstring)throwsIOException{
- super.sendError(status,string);
- this.status=status;
- }
-
- publicvoidsendError(intstatus)throwsIOException{
- super.sendError(status);
- this.status=status;
- }
-
- publicvoidsendRedirect(Stringlocation)throwsIOException{
- super.sendRedirect(location);
- this.status=SC_MOVED_TEMPORARILY;
- }
-
- publicPrintWritergetWriter()throwsIOException{
- if(outputType==OUTPUT_STREAM)
- thrownewIllegalStateException();
- elseif(outputType==OUTPUT_WRITER)
- returnwriter;
- else{
- outputType=OUTPUT_WRITER;
- writer=newPrintWriter(newOutputStreamWriter(buffer,
- getCharacterEncoding()));
- returnwriter;
- }
- }
-
- publicServletOutputStreamgetOutputStream()throwsIOException{
- if(outputType==OUTPUT_WRITER)
- thrownewIllegalStateException();
- elseif(outputType==OUTPUT_STREAM)
- returnoutput;
- else{
- outputType=OUTPUT_STREAM;
- output=newWrappedOutputStream(buffer);
- returnoutput;
- }
- }
-
- publicvoidflushBuffer()throwsIOException{
- if(outputType==OUTPUT_WRITER)
- writer.flush();
- if(outputType==OUTPUT_STREAM)
- output.flush();
- }
-
- publicvoidreset(){
- outputType=OUTPUT_NONE;
- buffer.reset();
- }
-
- /**
- *Callthismethodtogetcachedresponsedata.
- *
- *@returnbytearraybuffer.
- *@throwsIOException
- */
- publicbyte[]getResponseData()throwsIOException{
- flushBuffer();
- returnbuffer.toByteArray();
- }
-
- /**
- *ThisclassisusedtowrapaServletOutputStreamandstoreoutputstream
- *inbyte[]buffer.
- */
- classWrappedOutputStreamextendsServletOutputStream{
-
- privateByteArrayOutputStreambuffer;
-
- publicWrappedOutputStream(ByteArrayOutputStreambuffer){
- this.buffer=buffer;
- }
-
- publicvoidwrite(intb)throwsIOException{
- buffer.write(b);
- }
-
- publicbyte[]toByteArray(){
- returnbuffer.toByteArray();
- }
- }
-
- }
(2).GZipFilter类
Java代码
- publicclassGZipFilterimplementsFilter{
- publicvoidinit(FilterConfigarg0)throwsServletException{
- }
-
- publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,
- FilterChainchain)throwsIOException,ServletException{
-
- HttpServletResponsehttpResponse=(HttpServletResponse)response;
- CachedResponseWrapperwrapper=newCachedResponseWrapper(httpResponse);
- //写入wrapper:
- chain.doFilter(request,wrapper);
- //对响应进行处理,这里是进行GZip压缩:
- byte[]data=GZipUtil.gzip(wrapper.getResponseData());
- httpResponse.setHeader("Content-Encoding","gzip");
- httpResponse.setContentLength(data.length);
- ServletOutputStreamoutput=response.getOutputStream();
- output.write(data);
- output.flush();
- }
-
- publicvoiddestroy(){
-
- }
-
- }
(3).GZipUtil类
Java代码
- publicfinalclassGZipUtil{
- /***Doagzipoperation.*/
- publicstaticbyte[]gzip(byte[]data){
- ByteArrayOutputStreambyteOutput=newByteArrayOutputStream(10240);
- GZIPOutputStreamoutput=null;
- try{
- output=newGZIPOutputStream(byteOutput);
- output.write(data);
- }catch(IOExceptione){
- thrownewRuntimeException("G-Zipfailed.",e);
- }finally{
- if(output!=null){
- try{
- output.close();
- }catch(IOExceptione){
- }
- }
- }
- returnbyteOutput.toByteArray();
- }
- }
(4).在web.xml中配置 GZipFilter
Xml代码
- <filter>
- <filter-name>GZipFilter</filter-name>
- <filter-class>com.logcd.filter.GZipFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>GZipFilter</filter-name>
- <url-pattern>*.html</url-pattern>
- </filter-mapping>
分享到:
相关推荐
解决当内存资源不充足时大数据量的JSON文本解析为JSON对象会导致内存溢出的问题。 基于org.json的部分源代码,以及新增的JsonLazyer类。 原理:用时创建的规则降低传统解析器一次性将文本转成Java对象而占用大量内存...
自定义Filter来解决web项目中的乱码问题,包括get请求和post请求,使用包装设计模式。
简单可靠的filter源码和详细配置,轻松解决web中文乱码问题,web开发者必备神器你值得拥有!
1、Filter的理解和应用 实现一个禁止缓存的过滤器。 要求和提示: (1)禁止浏览器缓存所有动态页面; (2)有3个http响应头字段可以禁止浏览器缓存当前页面,它们在Servlet中的示例代码如下。 response....
Filter过滤器的代码及其web.xml配置代码 很好的解决网页乱码问题,很方便,只要按照名字添加就可以了
大数据量的问题是很多面试笔试中经常出现的问题,比如百度,谷歌,腾讯这样的一些涉及到海量数据的公司经常会问到。 本文的一些问题基本直接来源于公司的面试笔试题目。包括Bloom filter,Hashing,bit-map,双层桶...
1、修改tomcat下的Conf/web.xml文件,在该文件内容中新增以下配置,注意,若该web.xml中存在其它filter,则需要将该filter放在所有filter前面; <filter> <filter-name>CorsFilter</filter-name> <filter-class>...
web.xml 中的listener、 filter、servlet 加载顺序及其详解
一个jar包,包含: 一个可用的GZIP Filter 一个可用的Cache Filter
使用filter过滤器解决中文乱码问题,包含源码,以及filter的配置,希望能帮上大家
介绍如何在j2ee下的web应用,合理使用filter技术
web.xml配置filter和filtermapping,编写类 读取或写死filter的init-params中的字符编码传入 reqeust中 调用dofilter方法,乱码解决
第20章 filter在web开发中的应用 588 20.1 过滤器概述 588 20.2 filter api 589 20.2.1 filter接口 589 20.2.2 filterconfig接口 590 20.2.3 filterchain接口 590 20.3 过滤器的部署 591 20.4 过滤器的开发 ...
SurfControl Web Filter系统符合南航在网络功能上的需求,包括自动和手工方式相结合,达到对不良网站和非法网站进行过滤的目的,使管理功能比以前更强了,也实现了其需要的报表管理功能,能灵活的自动生成报表,以及...
第20章 filter在web开发中的应用 588 20.1 过滤器概述 588 20.2 filter api 589 20.2.1 filter接口 589 20.2.2 filterconfig接口 590 20.2.3 filterchain接口 590 20.3 过滤器的部署 591 20.4 过滤器的开发 ...
SurfControl Web Filter可以成本效益的方式对公司内任何位置的网络使用和滥用进行监控和控制,无论用户用什么方式或在何处上网此解决方案与软件或应用程序一样可部署,能够帮助用户全面理解所面临的威胁,并提供应对...
flex4,struts2.3兼容配置web.xml中的filter
本篇文章是介绍javax.servlet包中Filter的几个功能,一是字符编码过滤,二是拦截指文件夹中的文件,实现登录验证
XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin...
Filter程序开发与应用上机手册,内含有详细步骤与代码。