ビッグデータ公式21


ビッグデータ公式21
フィルタ
定義#テイギ#
Filter--フィルタサーブレットの中で最も実用的な技術であるJavaEEコア技術の一つである【サーブレット+Filter+Listener】リソースへのアクセスをブロックすることができ、ブロックした後に通過を許可できるかどうか、前または後に追加の単位操作を行うことができます.ブロックとは、要求を表すrequestオブジェクトとResponseオブジェクトをブロックすることです.責任チェーンパターン【順次ブロック、検査、制御】1つのリソースは、複数のフィルタによってブロックされることができる1つのブロッカーは、複数のリソースをブロッキングすることもできる.

図解


一般的な使用シーン
URLベースのアクセス制御権限全局乱符号解決フィルタ自動ログインフィルタ敏感語圧縮応答...

フィルタを実装するには
クラス実装Filterインタフェースを書く
public void init(FilterConfig arg0) throws ServletException
初期化方法
public void doFilter(final ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException
最も核心的な方法は、生存期間中に、この方法の実行をもたらし、論理コードを書けばになる.

public void destroy()
フィルタが破棄される前に呼び出す、後始末動作を実現する.

api


package com.peng.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterDemo implements Filter {

    public void destroy() {
        System.out.println("destory");
    }

    public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        System.out.println("kernel");
    }

    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("init");
    }

}

Webでxmlに配置するフィルタ


    FilterDemo
    com.peng.filter.FilterDemo



    FilterDemo
    /*


filterのライフサイクル
Webアプリケーションが起動すると、アプリケーションで構成されたフィルタオブジェクトが作成され、initメソッドが初期化され、その後、Webアプリケーションが破棄されるまでFilterが破棄され、再破棄される前にdestoryメソッドの論理が実行されます.生存期間中、資源に対するブロック処理(doFilter法)を行い、beforeとafter法を増やし、処理を行い、1層1層、1層1層出することができる.
呼び出しプロシージャ
1つのリソースが複数のフィルタによってブロックする場合、順序は「mapping」構成の順序である.



Filter関連オブジェクト
FilterConfigフィルタ構成オブジェクト
Initメソッドのパラメータfilter初期化パラメータを取得する
ServeretContextオブジェクトの取得例

    FilterDemo
    com.peng.filter.FilterDemo
    
        key1
        value1
    
    
        key2
        value2
    

public void init(FilterConfig arg0) throws ServletException {
    System.out.println("init");
    Enumeration initParameterNames = arg0.getInitParameterNames();
    while (initParameterNames.hasMoreElements()) {
        String name = initParameterNames.nextElement().toString();
        System.out.println(name + "~" + arg0.getInitParameter(name));
    }
}
効果の実行




FilterChain
doFilter関数のパラメータ代表フィルタチェーンdoFilterメソッドが提供され、実行後のフィルタ
public void doFilter(final ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {
    //       
    //     --     ,            
    arg2.doFilter(arg0, arg1);
}
が提供される.


Filterアプリケーション
全局スクランブル解決フィルタ
要求文字化け
GET方式
ソリューション1:パラメータを取得し、文字化けしを解決してから戻す
【問題あり:RequestメソッドsetParameterメソッドなし】

ソリューション2:requestのパケットは変更できず、元のメソッドのみを変更できます.
継承【ここでは使用できません】:既存のオブジェクトの改造は無効です.オブジェクトは生成されているため、新しいサブクラスオブジェクトをnewできません.
デコレーションモードを使用してrequestをデコレーションする方法【ここで使用可能】:
【getParameter(String key)】
【getParameterValues()】
【getParameterMap】
package com.easymall.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class EncodingFilter implements Filter {
    private String encode = null;

    //       
    public void init(FilterConfig arg0) throws ServletException {
        //   ServletContext  
        ServletContext sc = arg0.getServletContext();
        //          
        this.encode = sc.getInitParameter("encode");
    }

    public void doFilter(final ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        //     -get、post    
        MyServletRequest msr = new MyServletRequest((HttpServletRequest) arg0);
        //     
        arg1.setCharacterEncoding(encode);
        arg1.setContentType("text/html;charset=" + encode);
        //     
        arg2.doFilter(msr, arg1);
    }

    //        
    public void destroy() {

    }

    //      
    class MyServletRequest extends HttpServletRequestWrapper {
        private ServletRequest request = null;
        private boolean hasNoteEncode = true;

        public MyServletRequest(HttpServletRequest request) {
            super(request);
            this.request = request;
        }

        //     
        @Override
        public String getParameter(String name) {
            return this.getParameterValues(name) == null ? null : this
                    .getParameterValues(name)[0];
        }

        //     
        @Override
        public Map getParameterMap() {
            try {
                //  :   map     ,   --     
                @SuppressWarnings("unchecked")
                Map map = request.getParameterMap();
                if (hasNoteEncode) {
                    for (Map.Entry entry : map.entrySet()) {
                        String[] values = entry.getValue();
                        for (int i = 0; i < values.length; i++) {
                            values[i] = new String(
                                    values[i].getBytes("iso8859-1"), encode);
                        }
                    }
                    hasNoteEncode = false;
                }
                return map;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }

        //     
        @Override
        public String[] getParameterValues(String name) {
            return this.getParameterMap().get(name);
        }

    }
}


動的エージェント:エージェントオブジェクトによって改造され、エージェントオブジェクトによって被エージェントオブジェクトにアクセスする(ここで使用可能):
package com.easymall.filter;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class EncodingFilter implements Filter {
    private String encode = null;

    public void destroy() {

    }

    public void doFilter(final ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        //     -get--     
        //  ServletRequest   HttpServletRequest
        final HttpServletRequest hsr = (HttpServletRequest) arg0;
        // get  ---      
        // 2、      【  】
        //    :          。     :     .getClass().getClassLoader()
        //    :          。     :     .getClass().getInterfaces()
        //    :   【       】
        //              invoke     
        HttpServletRequest obj = (HttpServletRequest) Proxy.newProxyInstance(
                hsr.getClass().getClassLoader(), //           
                hsr.getClass().getInterfaces(), //             
                new InvocationHandler() {
                    //    : Object proxy     。  
                    //    : Method method           
                    //    : Object[] args             ,     
                    public Object invoke(Object arg0, Method method,
                            Object[] arg2) throws Throwable {
                        //   getParameter      
                        if ("getParameter".equals(method.getName())) {
                            //       
                            String m = hsr.getMethod();
                            if ("GET".equalsIgnoreCase(m)) {
                                //        
                                String invoke = (String) method.invoke(hsr,
                                        arg2);
                                String re = null;
                                try {
                                    //   
                                    re = new String(invoke
                                            .getBytes("iso8859-1"), encode);
                                } catch (Exception e) {
                                }
                                return re;
                            }
                        }
                        return method.invoke(hsr, arg2);
                    }
                });
        //     -post
        arg0.setCharacterEncoding(encode);
        //     
        arg1.setCharacterEncoding(encode);
        arg1.setContentType("text/html;charset=" + encode);
        //     
        arg2.doFilter(obj, arg1);
    }

    public void init(FilterConfig arg0) throws ServletException {
        ServletContext sc = arg0.getServletContext();
        this.encode = sc.getInitParameter("encode");
    }

}


POST方式
arg0.setCharacterEncoding(encode);

レスポンス文字化け
ソリューション
arg1.setCharacterEncoding(encode);
arg1.setContentType("text/html;charset=" + encode);


自動ログイン
フィルタなしのログイン


フィルタへのログイン


ユーザログイン処理時
初回ログイン時:自動ログインがチェックされているかどうかを判断する
No:ログインページに進みます.
はい--クッキーに保存します【注意:パスワードの機密性】
再アクセス時:
ユーザーがログインしていない+cookie情報アカウントのパスワードが正しい-->自動ログインすでに登録したことがあって、アカウントのパスワードが正しいかどうかを判断します-->正しいならば登録します

コード例
package com.easymall.filter;

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.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.easymall.domain.User;
import com.easymall.factory.BasicFactory;
import com.easymall.service.UserService;

public class AautologinFilter implements Filter {

    public void destroy() {

    }

    public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) arg0;
        HttpServletResponse response = (HttpServletResponse) arg1;
        //         
        if (request.getSession(false) == null
                || request.getSession().getAttribute("user") == null) {
            //     Cookie     
            Cookie[] cookies = request.getCookies();
            Cookie autoCookie = null;
            for (Cookie cookie : cookies) {
                if ("autologin".equals(cookie.getName())) {
                    autoCookie = cookie;
                }
            }
            if (autoCookie != null) {
                //       cookie              
                String username = URLDecoder.decode(autoCookie.getValue()
                        .split("#")[0], "utf-8");
                String password = autoCookie.getValue().split("#")[1];
                UserService userService = BasicFactory.getFactory().getObj(
                        UserService.class);
                if (userService.checkUsernameAndPassord(username, password)) {
                    //   session
                    HttpSession session = request.getSession();
                    //  session        
                    session.setAttribute("user", new User(-1, username, null,
                            null, null));
                    //     
                    response.getWriter().write("    !    。。。");
                    response.setHeader("refresh",
                            "2;url=" + request.getContextPath() + "/index.jsp");
                }
            }
        } else {//      
            //       ,        。。。。
        }
        //     
        arg2.doFilter(arg0, arg1);
    }

    public void init(FilterConfig arg0) throws ServletException {

    }

}
暗号化
MD 5暗号化アルゴリズム
特長
任意のサイズのバイナリはMD 5計算によりユニークな128ビットバイナリを得た.
同じデータで得られたMD 5の結果は同じであった.
異なるデータで得られたMD 5の結果はと異なる.
通常は16進数の32ビットデータに変換する.

データの概要、データの指紋----その後の比較適用
暗号化ストレージデータファイルの整合性デジタル署名...

EasyMallで暗号化すべき場所
Cookieに自動登録されたパスワードの記憶データベースにパスワードが格納されているレコードは、銘文レコードに記録すべきではありません.


コード例
package com.easymall.utils;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {
    /**
     *   md5       
     */
    public static String md5(String plainText) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText.getBytes());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("  md5    !");
        }
        String md5code = new BigInteger(1, secretBytes).toString(16);
        //       32 ,                 32 ,          ,         0  
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }
}
補足