フィルター
web.xmlに登録するか、クラスの頭に@WebFilterアノテーションを付け、Filterクラスをimplementsすると、フィルターを動作させることが出来ます。フィルターはサーブレット実行前後に処理を行うことができます。サーブレットの処理時間計測や文字コードなどの一括指定などが出来ます。
ログインしていない状態で直接アクセスを防ぐ場合、ここにログインチェック処理を埋め込むことで対応できます。
フィルターサンプル
package test;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@WebFilter("/*")
public class TestFilter implements Filter {
public TestFilter() {
System.out.println("TestFilter");
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("init");
}
public void destroy() {
System.out.println("destroy");
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
String encording = "UTF8";
// 遷移元の文字コード指定
request.setCharacterEncoding(encording);
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
String contextPath = req.getContextPath();
String uri = req.getRequestURI();
String method = req.getMethod();
System.out.println("アクセス:" + uri + ":" + method);
if (uri.equals(contextPath + "/login.jsp") || uri.equals(contextPath + "/Login")) {
// ログイン処理時はなにもしない
} else if (session == null || session.getAttribute("login") == null) {
// セッションが切れたらログイン画面に戻る
request.setAttribute("msg", "セッションが切れました");
RequestDispatcher rd = request.getRequestDispatcher("/login.jsp");
rd.forward(request, response);
return;
}
// 時間計測開始
long start = System.currentTimeMillis();
// サーブレットの実行
chain.doFilter(request, response);
// 時間計測終了
long end = System.currentTimeMillis();
System.out.println("処理時間:" + (end - start) + "ms");
// 遷移先の文字コード指定
response.setCharacterEncoding(encording);
}
}
@WebFilterアノテーションをつけているので、web.xmlに登録する必要はありません。 doFilterがメインメソッドになります。ここでサーブレットを呼び出すので、この前後の時間を測ることで処理の時間計測ができます。
引数のServletRequestからSessionが取得できるので、Sessionによるログインチェックができます。
またgetMethodメソッドよりGET、POST等が取得できるので、GETだけ処理を行うといったこともできます。
requestとresponseに対し、setCharacterEncodingメソッドで文字コードを指定しています。
ここで処理することにより各サーブレットで文字コードを指定する必要がなくなります。
フィルターの説明はこれで終わりですが、動作確認するため以下に簡易ログイン処理を作ってみました。
Login.java
package test;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
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 javax.servlet.http.HttpSession;
@WebServlet("/Login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Login() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// GETでアクセスされた場合、login.jspを表示
RequestDispatcher dispatch = request.getRequestDispatcher("login.jsp");
dispatch.forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String str = request.getParameter("str");
if (str == null) {
str = "";
}
// ログインチェック。IDがtestの場合、ログイン
if (str.equals("test")) {
// ログイン成功
HttpSession session = request.getSession();
session.setAttribute("login", str);
// メニュー画面に遷移
response.sendRedirect("menu.jsp");
} else {
// ログイン失敗
request.setAttribute("msg", "IDが不正です");
// ログイン画面に表示
RequestDispatcher dispatch = request.getRequestDispatcher("login.jsp");
dispatch.forward(request, response);
}
}
}
login.jspからPOSTでアクセスされるServletです。login.jspでIDにtestと指定された場合、ログイン成功としmenu.jspに遷移します。
それ以外はログイン失敗としてlogin.jspに戻ります。
Menu.java
package test;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
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 javax.servlet.http.HttpSession;
@WebServlet("/Menu")
public class Menu extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Menu() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String str = request.getParameter("str");
if (str == null) {
str = "";
}
// ログアウトが指定
if (str.equals("logout")) {
request.setAttribute("msg", "ログアウトしました");
// セッションの削除
HttpSession session = request.getSession();
session.invalidate();
RequestDispatcher dispatch = request.getRequestDispatcher("login.jsp");
dispatch.forward(request, response);
} else {
// メニューが指定されたときの処理(省略)
RequestDispatcher dispatch = request.getRequestDispatcher("menu.jsp");
dispatch.forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
menu.jspからアクセスされるServletです。menu.jspでログアウトが指定された場合、セッションを破棄し、login.jspに遷移します。
login.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
//セッションをクリア。画面表示時にログイン情報が削除される
session.invalidate();
String message = (String) request.getAttribute("msg");
if (message == null) {
message = "";
}
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>ログイン</title>
</head>
<body>
<form action="/test/Login" method="POST">
ID: <input type="text" name="str" /> <BR /> <input type="submit"
value="ログイン" /> <BR />
</form>
<%=message%>
</body>
</html>
ログイン画面です。IDを入力してログインボタンを押すと認証チェックを行います。 (testを入力するとログインできます)
menu.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>メニュー</title>
</head>
<body>
<h1>メニュー</h1>
工事中・・・
<br />
<a href="Menu?str=logout">ログアウト</a>
</body>
</html>
ログインに成功した場合、表示されるメニュー画面です。ログインせずに直接アクセスするとlogin.jspに戻されます。 ページのトップへ戻る