サーブレットフィルターのサンプルプログラム

サーブレットフィルターの動きをサンプルプログラムで確かめてみました。Servletの実行前後で処理をフィルターに任せることができるため、いくつかのServletで前処理、後処理が共通である場合はフィルターに集約することができます。

サーブレットフィルターの実行環境です。

Java: OpenJDK 1.8
Tomcat: ver 9.0.65

フィルターを適用するにはTomcatの web.xml に記載をします。

filterのurl-patternにアスタリスクを使うことで、TestServlet1、TestServlet2が動くときにTestFilterが動くようにしています。

TestFilterのソースコードです。

FilterインターフェイスのdoFilterメソッドに処理を記載しています。FilterChainのdoFilterメソッドで処理をServletに渡します。Servletの処理が終わったらフィルターに処理が戻ってきます。

ややこしいのは(Filterインターフェイスの)doFilterメソッドを実装した中で(FilterChainの)doFilterメソッドを呼ぶことです。なお、initとdestroyのメソッドは処理がないのでオーバーライドしているだけです。

TestServlet1のソースコードです。

TestServlet2のソースコードです。

TestServlet1とTestServlet2はprintlnで出力する文言が違うだけです。

TestServlet1を実行したときのものです。

TestServlet2を実行したときです。

どちらもフィルターの処理が動いていることがわかります。

フィルターは複数設定することもできます。その場合は web.xml に複数のフィルターを記載します。フィルターが実行される順番は記載した順(上から下)となります。

前処理と後処理のタイミングですが以下のようになります。①〜⑤が処理順を示します。

フィルターに処理が戻るときは web.xml に記載した下の方のフィルターから処理がされます。そのため、前処理と後処理ではフィルターの実行順序が逆になります。

使用したソースを載せておきます。

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
	http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">

<servlet>
	<servlet-name>servlet1</servlet-name>
	<servlet-class>sample5.TestServlet1</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>servlet1</servlet-name>
	<url-pattern>/sample5/servlet1</url-pattern>
</servlet-mapping>

<servlet>
	<servlet-name>servlet2</servlet-name>
	<servlet-class>sample5.TestServlet2</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>servlet2</servlet-name>
	<url-pattern>/sample5/servlet2</url-pattern>
</servlet-mapping>

<filter>
	<filter-name>filter</filter-name>
	<filter-class>sample5.TestFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>filter</filter-name>
	<url-pattern>/sample5/*</url-pattern>
</filter-mapping>

</web-app>

TestFilter.java


package sample5;

import java.io.IOException;
import java.io.PrintWriter;
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 TestFilter implements Filter {

	public void doFilter(
		ServletRequest request, ServletResponse response,
		FilterChain chain
	) throws IOException, ServletException {

		//Filterの前処理
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='UTF-8'>");
		out.println("<title>Filter Servlet</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("Filterの前処理<br>");
		request.setAttribute("out", out);
		
		//Servletの処理
		chain.doFilter(request, response);

		//Filterの後処理
		out.println("Filterの後処理<br>");
		out.println("</body>");
		out.println("</html>");
	}

	public void init(FilterConfig filterConfig) { }
	public void destroy() { }
}

TestServlet1.java


package sample5;

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 TestServlet1 extends HttpServlet {

	public void doGet (
		HttpServletRequest request, HttpServletResponse response
		) throws ServletException, IOException {
	
		PrintWriter out = (PrintWriter)request.getAttribute("out");
		out.println("Servlet(1)の処理<br>");		

	}
}

TestServlet2.java


package sample5;

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 TestServlet2 extends HttpServlet {

	public void doGet (
		HttpServletRequest request, HttpServletResponse response
		) throws ServletException, IOException {
	
		PrintWriter out = (PrintWriter)request.getAttribute("out");
		out.println("Servlet(2)の処理<br>");		

	}
}

クッキーのセッションID削除とTomcatのセッション破棄したときの動きの違い

クッキーのセッションIDを削除したときと、アプリケーションサーバー(Tomcat)が持つセッションを破棄したときの動きの違いを確かめてみました。

実行環境
OS: ubuntu 20.04 LTS
Java: OpenJDK 1.8
Tomcat: ver 9.0.65

クッキーの内容とセッションIDを表示するServletです。

※テキストエディタの画像を貼り付けたのでソースコードは最後に記載しておきます。

これをブラウザで実行したときの結果です。初回アクセスのためクッキーにはまだセッションIDが設定されていません。Tomcatが発行したセッションIDは表示されています。

もう一度、同じURLにアクセスします。クッキーにも同じセッションIDが設定されました。

クッキーの内容を削除するServletです。

※ソースコードは最後に記載しておきます。

クッキーの削除ですが、クッキーの生存期間をゼロにすることで削除します。

ブラウザで実行したときの結果です。クッキーに設定されいていたJSESSIONIDが削除されました。

クッキーの内容とセッションIDを表示させてみます。

クッキーに設定されているセッションIDを削除したので新しいセッションIDになるのかと思ったのですが、そうでもないようです。削除したはずのセッションIDがクッキーに設定されていました。おそらくですが、Tomcatが管理しているセッションIDをクッキーに再設定していると思われます。

セッションを破棄するServletです。

※ソースコードは最後に記載しておきます。

ブラウザで実行したときの結果です。セッションが削除されました。

クッキーの内容とセッションIDを表示させてみます。クッキーは前回と同じセッションIDとなっていますが、Tomcatが管理するセッションは新しいIDとなっています。

もう一度、同じURLにアクセスします。

クッキーのセッションIDも新しいものになりました。クッキーが保持していたセッションIDはすでに破棄されたものであるため、新しいセッションIDをTomcatがクッキーに再設定したようです。

ちなみにですが、Tomcatのセッションの保持期間はweb.xmlに記載します。session-configタグのsession-timeoutに分単位で記載します。デフォルトでは30分です。session-timeoutに-1を設定するとセッションは無期限で保持されます。


<web-app ..
	:
	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>
	:
</web-app>

使用したソースを載せておきます。

Show.java


package sample4;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

@WebServlet(urlPatterns={"/sample4/show"})
public class Show extends HttpServlet {

	public void doGet (
		HttpServletRequest request, HttpServletResponse response
		) throws ServletException, IOException {
	
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();

		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='UTF-8'>");
		out.println("<title>Show</title>");
		out.println("</head>");
		out.println("<body>");
		
		out.println("クッキーの表示<br>");		
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				String name = cookie.getName();
				String value = cookie.getValue();
				out.println(name + " : " + value + "<br>");
			}
		}
		
		out.println("セッションの表示<br>");
		HttpSession session = request.getSession();
		out.println("Session ID : "+ session.getId() +"<br>");

		out.println("</body>");
		out.println("</html>");
	}
}

CookieRemove.java


package sample4;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

@WebServlet(urlPatterns={"/sample4/cookieremove"})
public class CookieRemove extends HttpServlet {

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

		response.setContentType("text/html; charset=UTF-8");	
		PrintWriter out = response.getWriter();

		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='UTF-8'>");
		out.println("<title>Cookie Remove</title>");
		out.println("</head>");
		out.println("<body>");
		
		Cookie[] cookies = request.getCookies();
		if ( cookies != null ) {
			for ( Cookie cookie : cookies ) {
				cookie.setMaxAge(0);
				response.addCookie(cookie);
				out.println( cookie.getName() + "を削除<br>" );
			}
		}

		out.println("</body>");
		out.println("</html>");
	}
}

SessionRemove.java


package sample4;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

@WebServlet(urlPatterns={"/sample4/sessionremove"})
public class SessionRemove extends HttpServlet {

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

		response.setContentType("text/html; charset=UTF-8");	
		PrintWriter out = response.getWriter();

		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='UTF-8'>");
		out.println("<title>Session Remove</title>");
		out.println("</head>");
		out.println("<body>");

		HttpSession session = request.getSession();
		session.invalidate();
		out.println( "Session ID を削除<br>" );

		out.println("</body>");
		out.println("</html>");
	}
}