日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

全站压缩过滤器

發(fā)布時(shí)間:2025/7/14 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 全站压缩过滤器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

?package?com.techsboy.filter; import?java.io.ByteArrayOutputStream; import?java.io.IOException; import?java.io.OutputStreamWriter; import?java.io.PrintWriter; import?java.util.zip.GZIPOutputStream; 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.annotation.WebFilter; import?javax.servlet.http.HttpServletRequest; import?javax.servlet.http.HttpServletResponse; import?javax.servlet.http.HttpServletResponseWrapper;/** *?tip:?PrintWriter,ServletOutputStream,JspWriter的輸出過程*?response對(duì)象getOutputSteam()和getWriter()方法分別獲得ServletOutputStream?out*?和PrintWriter?writer輸出對(duì)象,out.write(..),out.print(..)和out.println(..)方法*?最終都要使用out的write(int?b)方法來輸出數(shù)據(jù)。writer.write(..),writer.print(..),*?writer.println(..)方法可以自定義指定的流(通過PrintWriter的構(gòu)造方法注入指定的流)*?來將字符流轉(zhuǎn)換成字節(jié)流輸出。JspWriter的輸出最終是輸出到PrintWriter的緩存的前面, *?(因此總是優(yōu)先輸出PrintWriter的數(shù)據(jù),在輸出JspWriter的數(shù)據(jù),除非調(diào)用flush()),*?因此在調(diào)用JspWriter輸出前會(huì)使用response獲得PrintWriter對(duì)象,將數(shù)據(jù)輸出到該對(duì)象*?指定的緩存中,然后再用PrintWriter對(duì)象輸出客戶端。*?由上可見,解決全站壓縮問題要把住前兩個(gè)輸出對(duì)象的最后輸出關(guān)口,在關(guān)口處獲得數(shù)據(jù)*?壓縮處理,然后在把壓縮后的數(shù)據(jù)輸出。(注意?struts2會(huì)獲取兩次PrintWriter對(duì)象)*?全站壓縮過濾器類,負(fù)責(zé)將所有輸出都經(jīng)過壓縮后反饋給客戶端*/ @WebFilter("/*") public?class?GZIPCompressFilter?implements?Filter?{/***?@see?Filter#doFilter(ServletRequest,?ServletResponse,?FilterChain)*/public?void?doFilter(ServletRequest?req,?ServletResponse?resp,?FilterChain?chain)?throws?IOException,?ServletException?{HttpServletRequest?request?=?(HttpServletRequest)req;HttpServletResponse?response?=?(HttpServletResponse)resp;//在壓縮前對(duì)response方法進(jìn)行改寫,采用繼承包裝類的方法實(shí)現(xiàn)MyHttpServletResponse?myResponse?=?new?MyHttpServletResponse(response);chain.doFilter(request,?myResponse);//提取源數(shù)據(jù)進(jìn)行壓縮,使用源輸出流輸出//獲取源數(shù)據(jù)byte[]?b?=?myResponse.getSourceData();if(b.length!=0){//帶緩存的字節(jié)數(shù)組輸出流,存放壓縮后的數(shù)據(jù)ByteArrayOutputStream?byteOut?=?new?ByteArrayOutputStream();//對(duì)源數(shù)據(jù)進(jìn)行壓縮GZIPOutputStream?gzip?=?new?GZIPOutputStream(byteOut);gzip.write(b);gzip.close();//將壓縮的數(shù)據(jù)輸出給客戶端,同時(shí)通知客戶端解壓縮格式和內(nèi)容長(zhǎng)度byteOut.flush();b?=?byteOut.toByteArray();response.setHeader("Content-Encoding",?"gzip");response.setContentLength(b.length);response.getOutputStream().write(b);}}/***?@see?Filter#init(FilterConfig)*/public?void?init(FilterConfig?fConfig)?throws?ServletException?{}@Overridepublic?void?destroy()?{} }/***?自定義類繼承HttpServletResponse包裝類,改寫父類response獲得輸出流的兩個(gè)方法,從而*?實(shí)現(xiàn)所有輸出的數(shù)據(jù)被指定到一個(gè)帶緩存的字節(jié)數(shù)組輸出流中,以便可以方便的獲得輸出的*?源數(shù)據(jù),來進(jìn)行壓縮操作。*/ class?MyHttpServletResponse?extends?HttpServletResponseWrapper?{private?ByteArrayOutputStream?byteOut?=?new?ByteArrayOutputStream();private?PrintWriter?writer?=?null;public?MyHttpServletResponse(HttpServletResponse?response)?{super(response);}/***?改寫父類的方法,創(chuàng)建一個(gè)類繼承ServletOutputStream(并注入一個(gè)帶緩存的字節(jié)數(shù)組輸出流對(duì)象),*?該類改寫父類的write(int?b)方法,使得使用該類對(duì)象的方法輸出的數(shù)據(jù)都將輸出到字節(jié)數(shù)組輸出流的*?緩存中?*/@Overridepublic?ServletOutputStream?getOutputStream()?throws?IOException?{MyServletOutputStream?myOut?=?new?MyServletOutputStream(byteOut);return?myOut;}/***?改寫父類的方法,返回一個(gè)帶自己設(shè)定輸出流的PrintWriter對(duì)象*/@Overridepublic?PrintWriter?getWriter()?throws?IOException?{//?這是錯(cuò)的,該輸出流將字符流轉(zhuǎn)換成字節(jié)流使用的是平臺(tái)默認(rèn)字符集編碼ISO-8859-1 //??PrintWriter?writer?=?new?PrintWriter(byteOut);//下面才是正解,不過要注意判斷writer是否已經(jīng)被創(chuàng)建過,創(chuàng)建過就不要再創(chuàng)建了, //否則第一個(gè)writer的內(nèi)容就得不到輸出。 //struts2就是這種情形,他會(huì)調(diào)用該方法兩次生成兩次writerif(writer==null)writer?=?new?PrintWriter(new?OutputStreamWriter(byteOut,super.getCharacterEncoding()),true);return?writer;}/***?獲取源數(shù)據(jù)的字節(jié)數(shù)組*?@return?源數(shù)據(jù)的一個(gè)字節(jié)數(shù)組*/public?byte[]?getSourceData(){try?{if(writer!=null){writer.close();}byteOut.flush();}?catch?(IOException?e)?{throw?new?RuntimeException(e);}return?byteOut.toByteArray();} }/***?實(shí)現(xiàn)ServletOutputStream的輸出流(注入一個(gè)帶緩存的字節(jié)數(shù)組輸出流),*?改寫了父類的write(int?b)方法,實(shí)現(xiàn)該輸出流輸出數(shù)據(jù)統(tǒng)一指定到字節(jié)數(shù)組輸出流緩存中。*/ class?MyServletOutputStream?extends?ServletOutputStream{private?ByteArrayOutputStream?byteOut;public?MyServletOutputStream(ByteArrayOutputStream?byteOut){this.byteOut?=?byteOut;}@Overridepublic?void?write(int?b)?throws?IOException?{byteOut.write(b);} }

轉(zhuǎn)載于:https://my.oschina.net/techsboy/blog/221988

總結(jié)

以上是生活随笔為你收集整理的全站压缩过滤器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。