Filterを使ってアクセスログを記録してみよう。今回はファイルの書き込みの復習も行う。
フォルダ構成
まずは今回作成するアプリのフォルダ構成だ。迷子になりそうなときに参照してほしい。
作成
1.新規動的WebプロジェクトからFilterLessonを作成する。WEB-INFの中にdataという空のフォルダを作成しておく。
サーブレット
2.新規サーブレットからcontroller/Main.javaを作成する。
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/Main")
public class Main extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
}
中身は余計な部分を削除しただけで何も行っていない。実行すると以下のように表示されるシンプルなものだ。
JSP
3.jspファイルも作成しよう。index.jspという名で以下のように作成する。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Hello Filter!
</body>
</html>
実行してみよう。以下のように表示されれば成功だ。
Filter
4.では今回の本題となるFilterを作成していこう。新規フィルターからfilter.LogFilter.javaを以下のように作成する。
package filter;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
@WebFilter("/*")
public class LogFilter implements Filter {
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//ServletContextを取得
ServletContext application=request.getServletContext();
//実行日時のjava.util.Dateインスタンス作成
Date current=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
//日付入のpathを作成
String path="/WEB-INF/data/"+sdf.format(current).toString()+".log";
//いつもの3段ラッピングを行うがgetRealPathを使って実行環境のパスを渡していることに注意)
//第2引数はappend->true(追記モード)
FileOutputStream fos=new FileOutputStream(application.getRealPath(path),true);
//コンソールにリアルパスを出力しておく
System.out.println(application.getRealPath(path));
OutputStreamWriter osw=new OutputStreamWriter(fos,"utf-8");
BufferedWriter bw=new BufferedWriter(osw);
sdf=new SimpleDateFormat("HH:mm:ss");
bw.write(sdf.format(current).toString());
//win環境では"¥t"
bw.write("\t");
//getServletPath()を行うためにダウンキャストを行う
bw.write(((HttpServletRequest)request).getServletPath());
bw.write("\t");
bw.write(((HttpServletRequest)request).getHeader("user-agent"));
//osに依存しない改行コード出力
bw.newLine();
bw.close();
chain.doFilter(request, response);
}
public void destroy() {
}
}
initとdoFilterとdestroyが自動的にオーバーライドされるが今回記述が必要なのはdoFilterのみだ。(余計な部分を削除し、並び順を変えている)
今回
@WebFilter(“/*”)
としているのでこのアプリ内のすべてのURLに対してこのフィルターが有効となる。
@WebFilter(“/Main”)
とすればMainにアクセスがあったときのみフィルターが有効となる。
復数のパターンを指定したい場合は以下のように記述する
@WebFilter(urlPatterns={“/Main“, “/index.jsp”})
実行
サーブレットからの起動とindex.jspからの起動をしよう。こうすることでアクセスログに記録されていく。
ファイルの場所
でファイルはどこにできたのだろうか?それはシステムアウトしてコンソールに表示してある以下のパスにある。
長くて驚くが問題ない、全部をコピーして黒い画面に移動してviの後ろに半角スペースを打って貼り付ければokだ。
以下のようにアクセスログが表示されれば成功だ。/Mainと/index.jspにアクセスがあったことがわかる
最後に
自分が作ったサイトやアプリがどのようにアクセスされているかを知るのにこういったログは有用だ。このフィルターは使い回しが効くのであなたの作ったアプリにも適用してもらいたい。
コメント