目次
実際の開発プロセスでは、特定のアクセスリソースをフィルタリングする必要があります。リクエストが特定の条件を満たすと、リクエストはターゲットリソースにアクセスできます。条件が満たされない場合、ターゲットリソースにアクセスできません。例:管理者の場合機能にアクセスするには、要求する前に、それが管理者権限であるかどうかを判断する必要があります。現在のユーザーが管理者権限である場合はアクセスでき、その逆も可能です。
フィルタ
フィルタは、Javaで事前定義されたインターフェイスであり、必要に応じてさまざまなコンテンツをフィルタリングできます。特定のフィルタリングコンテンツでは、実装クラスを自分で定義してから、インターフェイスにフィルタリングメソッドを実装する必要があります。クライアントブラウザがリクエストを送信すると、リクエストは次のようになります。実際のターゲットリソースにアクセスし、条件付きフィルターを実行してからターゲットリソースを要求する前に、このプロセスはフィルターを介して完了することができます。
特定のリソースにアクセスするときに、アクセスされたパスが存在する場合、フィルターは解放操作を実行し、後続のサーブレットコードを通常どおり実行します。この時点でアクセスパスが存在しない場合、フィルターは解放操作を実行しません。コンソールがフィルターの内容を出力するとき。
ケースコード:
手順:
- javax.servlet.Filterインターフェースを実装するクラスを作成します
- filterメソッドを書き直し、dofilterメソッドに注意してください
- web.xmlでフィルターを構成する(関数)
- 私がフィルターであることをサーブレットコンテナーに伝えます
- 他のリソースにアクセスするときにフィルタリング操作を実行するようにフィルターコンテナに指示します。
web.xmlコード:
<filter>
<filter-name>HelloFilter</filter-name>
<filter-class>com.james.filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HelloFilter</filter-name>
<!--表示当前filter所拦截的路径设置-->
<url-pattern>/demo2</url-pattern>
</filter-mapping>
HelloFilter(Filter)コード:
public class HelloFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* filter执行过滤 主要编写代码的方法 等效 Servlet中的service方法
* 代码的逻辑 一行一行执行的
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("入门过滤器执行 A");
//不放行就相当于 当前请求就结束了 直接响应回去
//放行 进入原来的链接路径 相当 于调用方法 DemoServlet.doGet(request,response)
//filterChain.doFilter(servletRequest , servletResponse) ;//放行代码
System.out.println("入门过滤器执行 B");
}
@Override
public void destroy() {
}
}
サーブレットコード:
public class DemoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo被访问了");
response.getWriter().print("demo");
}
}
実装プロセス:
ライフサイクル:
void init(FilterConfig config):プロジェクトの開始時に1回だけ実行される初期化メソッド
void doFilter(request、response、FilterChain chain):フィルタリングメソッドを実行します。これは、リクエストが一致したときに実行されます。
void destroy():破棄します。プロジェクトが削除されるか、サーバーがシャットダウンされると実行され、1回だけ実行されます。
サーブレット:デフォルトでは、初めてアクセスされ、サーブレットがサービスメソッドを実行するたびに初期化され、サーバーは破棄メソッドの実行を停止します
フィルタは単一インスタンスのスレッドで安全でないオブジェクトです(メンバー変数を指定しないでください)
サーバーが起動すると、サーバーはフィルターオブジェクトを作成し、フィルターのinitメソッドを呼び出して初期化操作を実装します。
リクエストが来ると、フィルターがこのパスに一致する場合、サーバーはスレッドプールからスレッドを取得し、スレッド内のフィルターのdoFilterメソッドを呼び出し、doFilterメソッドが解放操作を実行すると次の場所に到達します。
スレッドが正常に閉じられると、サーバーはフィルターのdestroyメソッドを呼び出して、破棄操作を実行します。
注:パスは1つのサーブレットでのみ実行できますが、パスは複数のフィルターで実行でき、フィルターにパスの優先順位の問題はありません。
文字化けしたフルスタックを解決します。
各サーブレットの最初の操作は処理と応答のエンコードであり、ブラウザーが要求を送信すると、フィルターを介して中国語の文字化けしたコードを処理することもできます。
Tomcat8.5では、getリクエストの中国語の文字化けしたコードは処理されましたが、投稿は処理されませんでした。postリクエストの場合、前の操作はrequest.setCharacterEncoding( "utf-8");を介して行われ、各サーブレットはこのコードの文を書き込む必要があります。非常に面倒です。フィルターを介して書き込むことができるのは1回だけで、複数のサーブレットに効果的です。
コードステップ:
- フィルタを書く
- フィルタを設定するパスは/ *です。
- フィルタの要求ロジックを記述します
package com.james.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(filterName = "EncodingFilter" , urlPatterns = "/*")
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//全站编码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//放行
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
リスナー
Javaプログラムでは、特定のものの実行を監視する必要があります。監視対象のオブジェクトがそれに応じて変更されたら、対応するアクションを実行する必要があります。
JavaWebにはさらに3つのドメインオブジェクトがあります。
ServletRequest HTTPSession ServletContext
今日は、ServletContextListerの簡単な要約を作成します。
8人のリスナーがいます:
- ドメインオブジェクトの作成と破棄の監視
- ServletRequestListener
- HttpSessionListener
- ServletContextListener
- ドメインオブジェクトペアを監視する属性操作
- ServletRequestAttributeListener
- HttpSessionAttributeListener
- ServletContextAttributeListener
- セッション中の特別なJavaBeanの特別な処理を監視する
- HttpSessionBingdingListener
- HttpSessionActivationListener
リスナーの主な概念:
イベントソース:イベントが発生したオブジェクト
イベント:何が起こったのか
リスナー:自分で実装する必要のあるインターフェイス。
ケースコード:
オンラインの人を数える例のステップ分析:
1.リスナーを作成し、HttpSessionListenerを実装します
2.セッション作成後の操作
- servletContextオブジェクトを取得します
- オンラインで人数を取得する
- 人の数がnullの場合は、人の数を1に設定します
- 人数がnullでない場合は、人数を+1 \に設定します。
3.セッション破棄後の操作
- servletContextオブジェクトを取得します
- オンライン番号を取得する
- 人数をservletContextフィールドに入力します
4.テスト用のサーブレットを作成します。
リスナー
package com.james.web.listener;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 登录成功 或者 退出登录 其实操作的是 session的创建和销毁
* 监听session的创建和销毁即可
*/
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
/**
* 数量+1
* httpSessionEvent 事件对象
*/
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
HttpSession session = httpSessionEvent.getSession();
System.out.println(session.getId()+",第一次被创建,放入servletContext中");
//获得全局的域对象
ServletContext sc = session.getServletContext();
//先获得原来的登录数量
Integer count = (Integer)sc.getAttribute("count");
//以前一定登录过
if(count != null && count !=0 ){ // 先判断非空 再判断值
count++;
}else{
count=1; //以前没有登录过
}
sc.setAttribute("count" , count);
}
/**
* 数量-1
*/
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
//获得session
HttpSession session = httpSessionEvent.getSession();
System.out.println(session.getId() +" : 即将销毁 , 退出登录");
//获得servletContext
ServletContext servletContext = session.getServletContext();
Integer count = (Integer)servletContext.getAttribute("count");
//表示当前一定有人正在登录状态
if(count != null && count >0 ){
count -- ;
}else{
count= 0 ;
}
servletContext.setAttribute("count" , count);
}
}
ログインする
package com.james.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "LoginServlet" , urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("登陆成功:" +request.getSession().getId());
}
}
ログアウト
package com.james.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "LoginOutServlet" , urlPatterns = "/loginOut")
public class LoginOutServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("退出了session:" + request.getSession().getId());
//销毁session
request.getSession().invalidate();
}
}
showCount:
package com.james.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "ShowLogin" , urlPatterns = "/showLogin")
public class ShowLogin extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().print("当前人数为:" + getServletContext().getAttribute("count"));
}
}
ページ:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/login">点我登录服务器-不需要做登录案例</a><br/>
<a href="${pageContext.request.contextPath}/loginOut">点我退出登录</a><br/>
<a href="${pageContext.request.contextPath}/showLogin">点我查看登录成功服务器人数</a>
当前登录人数为: ${count}<br/>
<%--jsp的底层有九大内置对象 默认自己调用request.getSession();--%>
</body>
</html>
セッションの作成(request.getsession())の破棄(request.getSession()。invalidate();)を通じて、モニターのメソッドが呼び出され、セッションの数が変更されます。最後に、ページに表示できます。