1. 程式人生 > >javaEE框架類——過濾器(Filter)

javaEE框架類——過濾器(Filter)

1簡介:

 - 過慮器能對客戶的請求進行預先處理,然後再將請求轉發給其他web元件。
 - 過慮器是在Servlet2.3規範中定義的,它可以對Web元件的,ServletRequest和ServletResponse進行檢查和修改。
 - 過慮器本身並不生成ServletRequest物件和ServletResponse物件,它只對web元件提供以下過慮功能:
   在web元件呼叫之前檢查request,並修改請求頭和請求正文。
   過慮器能夠在web元件被呼叫之後檢查response對像,修改響應頭和響應正文。

2.過濾器圖解:
這裡寫圖片描述

  1. 過濾器技術要點:
  1)可以攔截(在前端頁面與servlet之間進行)
  2
)可以攔截伺服器中的任意資源(jsp,html,jpg,servlet) 3)該攔截不影響訪問速度,而且可以放置多個過濾器 4)優先順序高於servlet,請求時先執行filter,響應時後執行filter 5) 有關路徑的說明: /* 攔截專案下的所有資源 *.jsp 攔截所有的jsp頁面 /jsps/* 攔截jsps目錄下的所有資源 /buy/* 攔截buy目錄(注意,不一定是真實資料夾,這裡指的是路徑中的一段)下的所有資源 /LoginServlet 只攔截該servlet login 只攔截名為“login”的servlet /jsps/
*.jsp ----非法路徑,因為裡面要求類似“*.jsp”這樣的格式只能放在開頭,不能放在後面 6)如果配置了多個過濾器,它們的先後位置(從前端到後臺方向的先後順序)是以“filter-mapping” 的書寫順序來定的

3.建立自定義的過慮器:
自定義的過慮器必須實現:javax.servlet.Filter介面。此介面定義了以下三個方法:

  • Init(FilterConfig conf) – 過慮器的初始化方法。-初始化工作執行一次(啟動時)。
  • doFilter(ServletRequest,ServletResponse,FilterChain) –
    此方法完成實際的過慮操作。只要是配置的url匹配此過慮器的配置,即執行此方法。
  • destroy()-Servlet視窗在銷燬過慮器時執行此方法。-銷燬工作也只執行一次。

4.過濾器配置說明:

過慮器的配置:以下幾乎是所有單位的標準配置
<filter>
  <filter-name>autoLoginFilter</filter-name>
  <filter-class>cn.itcast.autologinfilter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>autoLoginFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
filter-name是過慮器的名稱
filter-class是過慮器的類檔案
init-param是過慮器的初始化引數。
param-name – 是引數名。
param-value - 是引數值。
filter-mapping是過慮器的對映資訊。
url-pattern-是需要過慮的資源url.
dispatcher-需要攔截的導向頁面屬性(基於url-pattern設定)

注意:

 - Filter-mapping子的元素: 對於一個<filter/>元素,可以設定多個filter-mapping對應的元素。
   <serlvet-name/>如果不配置<url-pattern/>元素,也可以通過配置<serlvet-name/>元素的形式設定需要攔截的Servlet。
   <dispatcher/>元素:可以為FORWARD- INCLUDE- REQUEST(預設)-
   ERROR之一。指定需要攔截的Servlet的請求試。
  <filter-mapping>
    <filter-name>login</filter-name>
    <url-pattern>/servlet/*</url-pattern>
    <url-pattern>/jsps/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping>


這裡的的dispatcher只攔截/servlet/和/jsps/的forward頁面,並不是所有的forward頁面

5.應用場景:

  • 黑名單
  • 爬蟲重複URL檢測
  • 代理快取技術
  • 設定通用功能(代理)
  • 不文明話語過濾(管理員踢人)
  • 自動登入(登入儲存技術)

6.自動登入程式碼實現:
index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>這是主頁</title>
  </head>

  <body>
     <h3>這是主頁</h3>
     <a href="<c:url  value='/css/table.css' />">訪問css</a>
     <hr/>

      <c:if test="${!empty sessionScope.error}">
         ${sessionScope.error}
        <c:remove var="error" scope="session"/>
      </c:if>

     <c:if test="${empty sessionScope.user }" var="boo">
         <form action="<c:url value='/LoginServlet'/>" method="post">
             Name:<input type="text" name="name"><br/>
              Pwd:<input type="text" name="pwd"><br/>
             <input type="submit" value="登入">
             <input type="radio" name="time" value="0" checked="checked">   不儲存
              <input type="radio" name="time" value="1">一天 
            <input type="radio" name="time" value="7">七天
          </form>
      </c:if>
      <c:if test="${!boo}">
        ${user.name }歡迎回來!
         <a href="<c:url value='/jsps/show.jsp'/>">瀏覽商品</a><br/>
         <a href="<c:url value='/CancelAutoLoginServlet'/>">取消自動登入</a>
      </c:if>
  </body>
</html>

字元過濾器CharacterFilter.java

package cn.hncu.pubs;

import java.io.IOException;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;


public class CharacterFilter implements Filter {
    private String charset;


    public void destroy() {

    }


    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding(charset);
        response.setCharacterEncoding(charset);
        HttpServletResponse resp=(HttpServletResponse) response;
        chain.doFilter(request, resp);
    }
    public void init(FilterConfig fConfig) throws ServletException {
        charset=fConfig.getInitParameter("charset");
    }

}

自動登入過濾器AutoLoginFilter.java

package cn.hncu.pubs;

import java.io.IOException;
import java.net.URLDecoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import cn.hncu.domain.User;

public class AutoLoginFilter implements Filter {

    public AutoLoginFilter() {
    }

    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest) request;
        Cookie cs[]=req.getCookies();
        if (cs!=null) {
            for (Cookie c : cs) {
                if (c.getName().equals("autoLogin")) {
                    String value = c.getValue();
                    String[] strs = value.split("@#");
                    String name = URLDecoder.decode(strs[0], "utf-8");
                    String pwd = URLDecoder.decode(strs[1], "utf-8");

                    if (name.equals(pwd)) {
                        User user = new User();
                        user.setName(name);
                        user.setPwd(pwd);
                        System.out.println(user);
                        req.getSession().setAttribute("user", user);
                    }
                    break;
                }
            }
        }
        chain.doFilter(req, response);
    }

    public void init(FilterConfig fConfig) throws ServletException {
    }


}

LoginServlet.java

package cn.hncu.servlet;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hncu.domain.User;

public class LoginServlet extends HttpServlet {


    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        String name=request.getParameter("name");
        String pwd=request.getParameter("pwd");
        String time=request.getParameter("time");
        User user=new User();
        user.setName(name);
        user.setPwd(pwd);
        if (name!=null&&name.trim().length()>0&&pwd!=null) {
            if (name.equals(pwd)) {
                //登入成功,就往客戶端寫一個cookie,將使用者名稱和密碼存到cookie中
                //為了能夠相容中文,要進行編碼
                name=URLEncoder.encode(name, "utf-8");
                pwd=URLEncoder.encode(pwd, "utf-8");
                Cookie cookie=new Cookie("autoLogin", name+"@#"+pwd);
                cookie.setPath(request.getContextPath());
                cookie.setMaxAge(60*60*24*Integer.parseInt(time));//分鐘為單位
                response.addCookie(cookie);
                request.getSession().setAttribute("user", user);
            }else{
                request.getSession().setAttribute("error", "使用者名稱或者密碼錯誤");
            }
        }else{
            request.getSession().setAttribute("error", "使用者名稱或者密碼不能為空");
        }
        response.sendRedirect(request.getContextPath()+"/index.jsp");
    }
}

web.xml配置檔案

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name></display-name>
   <filter>
    <filter-name>CharacterFilter</filter-name>
    <filter-class>cn.hncu.pubs.CharacterFilter</filter-class>
    <init-param>
      <param-name>charset</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <filter>
    <filter-name>AutoLoginFilter</filter-name>
    <filter-class>cn.hncu.pubs.AutoLoginFilter</filter-class>
    <init-param>
      <param-name>charset</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>

   <filter-mapping>
    <filter-name>AutoLoginFilter</filter-name>
    <url-pattern>/LoginServlet</url-pattern>
    <url-pattern>/index.jsp</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>CharacterFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
   <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>CancelAutoLoginServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.CancelAutoLoginServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>CancelAutoLoginServlet</servlet-name>
    <url-pattern>/CancelAutoLoginServlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>