1.javaサーブレットフィルター(フィルター)
フィルターはサーブレットフィルターであり、サーブレット2.3仕様に追加された新機能であり、主にエンコードフィルタリング、ユーザーのログインステータスの判断などの一般的な操作を完了するために使用されます。
フィルタはフィルタと呼ばれ、その主な機能は、サーブレットの応答処理の前後にいくつかの特別な機能を実現するために、サーブレットコンテナによってサーブレットを呼び出すプロセスをインターセプトすることです。
注:フィルターはサーバーにデプロイされます。
ユーザーがブラウザーを介してサーバー内のターゲットリソースにアクセスすると、最初にフィルターによってインターセプトされ、フィルターで前処理操作が実行されてから、要求がターゲットリソースに転送されます。サーバーはこの要求を受信すると、それに応答します。応答を処理するプロセスでは、サーバーは、クライアントに送信する前に、フィルターを介して応答結果を処理する必要もあります。
基本的に、Filterはjavax.servlet.Filterインターフェースを実装するクラスであり、javax.servlet.Filterインターフェースで3つのメソッドが定義されています。
表の3つのメソッドはすべて、フィルターのライフサイクルを表すことができるメソッドです。init()メソッドはWebアプリケーションのロード時に呼び出され、destroy()メソッドはWebアプリケーションのアンロード(またはクローズ)時に呼び出されます。 )各メソッドは1回だけ呼び出され、doFilter()メソッドは複数回呼び出されます(クライアントが呼び出されるように要求している限り)。Filterのすべての作業はdoFilter()メソッドに集中します。
次の例は、フィルタプログラムがサーブレットプログラムの呼び出しプロセスをインターセプトする方法を示しています。
1.ターゲットリソースとして機能するサーブレットを作成します
package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyTestServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("MyTestServlet----");
PrintWriter out=resp.getWriter();
out.write("Hello MyServlet");
out.close();
}
}
2.フィルターを作成します
- 1.新しいクラスを作成し、javax.servlet.Filterインターフェースを実装します
- init、doFilter、およびdestroyメソッドを書き直します
- doFilterに特定のフィルタリングアクションを書き込む
- Web.xml構成フィルター
package com.wangxing.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 MyTestFilter implements Filter{
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("init方法初始化过滤器");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
System.out.println("doFilter方法过滤请求/响应对象");
//FilterChain chain---过滤器链对象
//doFilter(req, resp)---将请求/响应对象传递给下一个过滤器/目标资源
chain.doFilter(req, resp);
}
@Override
public void destroy() {
System.out.println("destroy方法销毁过滤器对象");
}
}
Web.xml
<filter>
<filter-name>myfilter1</filter-name>
<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mytest</servlet-name>
<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mytest</servlet-name>
<url-pattern>/mytest</url-pattern>
</servlet-mapping>
と试http:// localhost:8080 / TestFilterDemo1 / mytest
注:フィルターは、サーブレット/ターゲットリソースの処理を必要とせずに、ユーザーの要求に直接応答できます。
2. Javaサーブレットフィルタの2つのマッピング方法フィルタ
を作成した後、web.xmlの対応する構成情報はフィルタマッピングです。フィルタマッピング方法は、2つのタイプに分けることができます。
1.ワイルドカードを使用して、ユーザーからのすべてのリクエストをインターセプトします[ -allリクエスト]
<filter>
<filter-name>myfilter1</filter-name>
<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.さまざまな方法でアクセス要求
をインターセプトします。web.xmlファイルでは、フィルターがインターセプトするリソースを使用して各要素を構成できます。要素には特別な子要素があり、フィルターによってインターセプトされたリソースがサーブレットコンテナーによってどのように呼び出されるかを指定するために使用されます。4つの要素値があります。
例えば:
<filter>
<filter-name>myfilter1</filter-name>
<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter1</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
次に例を
示します。FORWARDがRequestDispatcherのforward()メソッドを介してリソースにアクセスすることを示している場合、現在構成されているフィルターが使用されます。RequestDispatcherのforward()メソッドを使用せずにリクエストを送信すると、現在構成されているフィルターは使用されません。
3.さまざまなアクセスパスのアクセス要求をインターセプト
する設定要素でさまざまなアクセスパスを指定することにより、現在のフィルターにアクセスできるリソースと現在のフィルターにアクセスできないリソースを決定します。
<filter>
<filter-name>myfilter1</filter-name>
<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter1</filter-name>
<url-pattern>/mytest</url-pattern>
</filter-mapping>
<filter>
<filter-name>myfilter2</filter-name>
<filter-class>com.wangxing.filter.MyOtherFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter2</filter-name>
<url-pattern>/myother</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mytest</servlet-name>
<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mytest</servlet-name>
<url-pattern>/mytest</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>myother</servlet-name>
<servlet-class>com.wangxing.servlet.OtherTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myother</servlet-name>
<url-pattern>/myother</url-pattern>
</servlet-mapping>
http:// localhost:8080 / TestFilterDemo3 / mytest
http:// localhost:8080 / TestFilterDemo3 / myother
3. FilterChain(フィルターチェーン)の詳細説明
複数のフィルタープログラムをWebアプリケーションに登録し、各フィルタープログラムを特定のURLで傍受することができます。複数のフィルタープログラムが同じURLをインターセプトする場合、これらのフィルターはフィルターチェーン(フィルターチェーンとも呼ばれます)を形成します。
FilterチェーンはFilterChainオブジェクトで表されます。FilterChainオブジェクトにはdoFilter()メソッドがあります。このメソッドの機能は、Filterチェーンの現在のフィルターを通過させ、リクエストを次のFilterに入力させることです。
上の図では、ブラウザーがWebサーバー内のリソースにアクセスするときに、2つのフィルターFilter1とFilter2を通過する必要があります。まず、Filter1がこのリクエストをインターセプトします。リクエストがFilter1で処理された後、FilterチェーンのFilterChainオブジェクトを介してdoFilter()メソッドを呼び出すことにより、リクエストがFilter2に渡されます。Filter2がユーザーリクエストを処理した後、同じFilterChainオブジェクトがdoFilter()メソッド、そして最後にリクエストがターゲットリソースに送信されました。Webサーバーがこの要求に応答すると、フィルターによってもインターセプトされますが、インターセプトシーケンスは前のシーケンスとは逆になり、応答結果は最終的にクライアントブラウザーに送信されます。
例えば:
<filter>
<filter-name>base</filter-name>
<filter-class>com.wangxing.filter.BaseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>base</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>myfilter2</filter-name>
<filter-class>com.wangxing.filter.MyOtherFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter2</filter-name>
<url-pattern>/mytest</url-pattern>
</filter-mapping>
<filter>
<filter-name>myfilter1</filter-name>
<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter1</filter-name>
<url-pattern>/mytest</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mytest</servlet-name>
<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mytest</servlet-name>
<url-pattern>/mytest</url-pattern>
</servlet-mapping>
http:// localhost:8080 / TestFilterDemo3 / mytest
フィルタチェーン内の各フィルタは、web.xmlファイルで設定されているのと同じ順序で実行されます。
4.
FilterConfigインターフェイスとその使用法の詳細な説明FilterConfigインターフェイスは、前に学習したServletConfigインターフェイスに似ています。
FilterConfigは、web.xmlファイル内のFilterプログラムの構成情報を取得するためにサーブレットAPIによって提供されるインターフェースです。このインターフェースは、web.xml内のFilterプログラムのすべての登録情報をカプセル化し、これらの構成を取得する一連の情報を提供します。情報メソッド。
FilterConfigのインターフェイスメソッドをテストします
package com.wangxing.filter;
import java.io.IOException;
import java.util.Enumeration;
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 MyTestFilter implements Filter{
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("init方法初始化过滤器");
//测试FilterConfig接口对象的常用方法
//String getFilterName()--- web.xml 文件中为 Filter 所设置的名称.
String filtername=config.getFilterName();
System.out.println("filtername=="+filtername);
//String getInitParameter(String name)---得到web.xml文件中配置的指定的初始化参数值
String myname=config.getInitParameter("myname");
System.out.println("myname=="+myname);
//Enumeration getInitParameterNames()---得到web.xml文件中配置的初始化参数的名称。
Enumeration<String> initnameString=config.getInitParameterNames();
// 遍历所有的初始化参数名,得到相应的参数值并打印
while (initnameString.hasMoreElements()) {
String paramname = initnameString.nextElement();
String value = config.getInitParameter(paramname);
System.out.println("初始化信息=="+paramname+"="+value);
}
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
System.out.println("MyTestFilter---doFilter方法过滤请求/响应对象");
chain.doFilter(req, resp);
}
@Override
public void destroy() {
System.out.println("destroy方法销毁过滤器对象");
}
}
Web.xml
<filter>
<filter-name>myfilter</filter-name>
<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
<init-param>
<param-name>myname</param-name>
<param-value>zhangsan</param-value>
</init-param>
<init-param>
<param-name>myaddress</param-name>
<param-value>西安</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
サーバーを起動して実行結果を確認します
5.サーブレットフィルタは、サイト全体の統一されたエンコーディングを実現し、中国語の文字化けの問題を解決し
ます。注:tomcat8の後のデフォルトのエンコーディング形式はutf-8で、7より前のエンコーディング形式はiso8859-1です。
package com.wangxing.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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 编码过滤器【全站统一编码,解决中文乱码问题】
* @author Administrator
*
*/
public class EncodingFilter implements Filter{
private String encoding="utf-8";
@Override
public void init(FilterConfig confing) throws ServletException {
this.encoding=confing.getInitParameter("encoding");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//转换ServletRequest为HttpServletRequest
HttpServletRequest req=(HttpServletRequest)request;
//转换ServletResponse为HttpServletResponse
HttpServletResponse resp=(HttpServletResponse)response;
//设置请求和响应的字符编码
//解决post请求的中文乱码
req.setCharacterEncoding(this.encoding);
resp.setCharacterEncoding(this.encoding);
resp.setContentType("text/html;charset="+this.encoding);
//解决get请求的中文乱码
//重写getParameter方法
// 对 request 进行包装
CharacterRequest characterRequest = new CharacterRequest(req,this.encoding);
chain.doFilter(characterRequest, resp);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
package com.wangxing.filter;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* 对 request 进行包装
* @author Administrator
*
*/
public class CharacterRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
private String encoding="utf-8";
public CharacterRequest(HttpServletRequest request,String encoding) {
super(request);
this.request=request;
this.encoding=encoding;
}
@Override
public String getParameter(String name) {
String value = request.getParameter(name);
if (value == null) {
return null;
}
//得到请求的提交方式
String method = request.getMethod();
if ("get".equalsIgnoreCase(method)) {
try {
//tomcat8以后默认编码格式是utf-8;7之前的都是iso8859-1
value = new String(value.getBytes(this.encoding), this.encoding);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
return value;
}
}
package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyTestServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("MyTestServlet----");
String myname=req.getParameter("myname");
System.out.println("myname=="+myname);
PrintWriter out=resp.getWriter();
out.write("Hello MyServlet==myname=="+myname);
out.close();
}
}
Web.xml
<filter>
<filter-name>encodingfilter</filter-name>
<filter-class>com.wangxing.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>mytest</servlet-name>
<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mytest</servlet-name>
<url-pattern>/mytest</url-pattern>
</servlet-mapping>
T试
http:// localhost:8080 / EncodingFilter / mytest?myname =%E5%BC%A0%E4%B8%89