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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

javaweb 中的过滤器 包装器

發布時間:2025/6/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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);
?? ?}

}





轉載于:https://www.cnblogs.com/clnchanpin/p/6852725.html

總結

以上是生活随笔為你收集整理的javaweb 中的过滤器 包装器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。