過濾器{
定義:Servlet的API中提供了一個Filter接口,當web開始時,某個類實現了該接口,那麼該類就叫做過濾器。通過過濾器,開發人員可以在用戶訪問某個資源之前,對訪問的請求和響應進行攔截。(當有多個過濾器,資源就會通過每一個過濾器)
步驟:
作用:1.實現filter接口
@Override public void init(FilterConfig filterConfig) throws ServletException { // 服務器啓動時過濾器就被創建,執行該方法!只創建一次 // filterConfig對象可以獲得web.xml文件配置的參數數據 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 作用是將攔截下來的請求.響應進行放行 chain.doFilter(request, response); } @Override public void destroy() { //web應用被移除,或者web服務器停止時,過濾器就會被銷燬,同時執行該方法! }
2.在web.xml文件進行定義
<filter> <filter-name>filterDemo</filter-name> <filter-class>cn.review.servlet.FilterDemo</filter-class> <init-param><!--定義一些參數,可以在過濾器中獲取該數據 --> <param-name></param-name> <param-value></param-value> </init-param> </filter> <filter-mapping> <filter-name>filterDemo</filter-name> <url-pattern>/*</url-pattern><!--定義攔截的路徑--> <!--指定攔截器攔截哪種方式訪問資源。request.forward.error.include --> <!-- 可以配置多個 --> <dispatcher>REQUEST</dispatcher> </filter-mapping>
1.通過檢查用戶的權限,來判斷是否允許用戶訪問資源
2.通過攔截,解決瀏覽器和服務器之間的亂碼
3.在過濾器放行之後,拿到response的內容,進行壓縮處理等設置
}
實例{
解決全站的請求亂碼問題
將數據進行壓縮輸出@Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { // 爲了調用子類方法 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 指定post提交編碼 request.setCharacterEncoding("UTF-8"); // 指定響應輸出的編碼 //response的編碼 response.setCharacterEncoding("UTF-8"); //通知瀏覽器打開方式 response.setHeader("content-type", "text/html;charset=utf-8"); // 放行 // 爲了解決get提交的亂碼問題,採用包裝設計模式,進行操作 chain.doFilter(new MyRequest(request), response); } // 繼承request的包裝類 class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest request= null; public MyRequest(HttpServletRequest request) { // 需要給包裝類傳遞一個被包裝的對象 super(request); this.request = request; } // 增強方法,解決get參數亂碼 @Override public String getParameter(String name) { if(name==null || name.trim().equals("")){ return null; } String value = request.getParameter(name); if(value==null || value.trim().equals("")){ return null; } try { return new String(value.getBytes("iso8859-1"),request.getCharacterEncoding()); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } }
@Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 爲了獲得response的數據,需要定義一個增強類, MyResponse myResponse = new MyResponse(response); chain.doFilter(request, myResponse); // 拿到緩衝流的數據 byte[] data = myResponse.getBos(); // 定義壓縮類 ByteArrayOutputStream bos = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(bos); // 把數據壓縮寫到了bos緩衝流 gzip.write(data); gzip.close(); byte[] gzipData = bos.toByteArray(); // 使用response對象將數據寫出並告訴瀏覽器壓縮格式 response.setHeader("content-encoding", "gzip"); response.setHeader("content-length", gzipData.length+""); response.getOutputStream().write(gzipData); } class MyResponse extends HttpServletResponseWrapper{ // 定義一個緩衝流,存儲response的數據 ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 先需要獲得被增強的對象,需要使用他的方法 HttpServletResponse response = null; public MyResponse(HttpServletResponse response) { super(response); this.response = response; } @Override public ServletOutputStream getOutputStream() throws IOException { // 當獲得輸出流的時候,傳遞一個自定義的流。以便將數據全部寫入緩衝流 return new MyOutputStream(bos); } public byte[] getBos(){ return bos.toByteArray(); } } class MyOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bos; public MyOutputStream(ByteArrayOutputStream bos) { super(); this.bos = bos; } @Override public void write(int b) throws IOException { bos.write(b); } }
}