Webアプリケーションのデータの保存はデータベースが基本だが、データベースを使うまでもないちょっとした処理ならばファイルの読み書きで済ましてしまうことも多い。今回はServletからのファイルの読み書きを練習しよう。
1.まずは新規動的アプリケーションから[joytas10]アプリを作成する。
2.controllerパッケージ内にFileWrite.java(Servlet)を以下のように作成する。
●controller.FileWrite.java

package controller;

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.RequestDispatcher;
import javax.servlet.ServletContext;
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("/FileWrite")
public class FileWrite extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/view/filewrite.jsp");
		rd.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				
	}
}

3.FileWriteのviewを作成しよう。WEB−INF/の中にviewフォルダを作成し、filewrite.jspを以下のように作成する。フォームとリンクを表示するだけのシンプルなviewだ。
●filewrite.jsp(/WEB-INF/view/filewrite.jsp”)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Joytas10</title>
</head>
<body>
<form action="/joytas10/FileWrite" method="post">
memo:<input type="text" name="memo"><button type="submit">保存</button>
</form>
<a href="/joytas10/FileRead">一覧</a>
</body>
</html>

4.サーブレットFileWriteから実行してみよう。以下のように表示されれば成功だ。

5.ではこのフォームに入力された内容をファイルに書き込むようFileWriteサーブレットにdoPostを追記しよう。
●controller.FileWrite.java

package controller;

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.RequestDispatcher;
import javax.servlet.ServletContext;
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("/FileWrite")
public class FileWrite extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/view/filewrite.jsp");
		rd.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//以下を追記
		request.setCharacterEncoding("UTF-8");
		String memo=request.getParameter("memo");
		ServletContext application=this.getServletContext();
		String path=application.getRealPath("/WEB-INF/data/memo.txt");
		System.out.println(path);
		FileOutputStream fos=new FileOutputStream(path,true);
		OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
		BufferedWriter bw=new BufferedWriter(osw);
		Date now=new Date();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String date=sdf.format(now);
		bw.write(date);
		bw.write("\t");
		bw.write(memo);
		bw.newLine();
		bw.close();
		response.sendRedirect("/joytas10/FileWrite");		
	}
}

6.実際にFileWriteサーブレットから実行してmemoを入力し、保存ボタンを押す。
7.作成ファイルを確認する。上記サーブレット33行目でシスアウトしているので、コンソールにパスが表示されている。そこで示されるフォルダに行ってみよう。memo.txtが作成されているはずだ。

「ポイント解説」
上記サーブレット31,32行部分に注目だ。サーブレットからのファイルのアクセスにはapplication.getRealPathを使ってパスを取得する。このように記述しておくことでサーバーの移動などが行われてもここは修正無しですむ。

ServletContext application=this.getServletContext();
String path=application.getRealPath("/WEB-INF/data/memo.txt");

8.ファイルへの書き込みに成功したので、続いてこのファイルの読み込みをしてみよう。まずはcontroller内にFileRead.javaを以下のように作成する。
●controller.FileRead,java(Servlet)

package controller;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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("/FileRead")
public class FileRead extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
		ServletContext application=this.getServletContext();
		String path=application.getRealPath("/WEB-INF/data/memo.txt");
		BufferedReader br=null;
		try {
			FileInputStream fis = new FileInputStream(path);
			InputStreamReader isr=new InputStreamReader(fis,"UTF-8");
			br=new BufferedReader(isr);
			List<String> lines=new ArrayList<>();
			String line;
			while((line=br.readLine())!=null){
				lines.add(0,line);
			}
			request.setAttribute("lines", lines);
			RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/view/fileread.jsp");
			rd.forward(request, response);
		} catch (FileNotFoundException e) {
			//ファイル未生成の場合書き込みに飛ばす。
			response.sendRedirect("/joytas10/FileWrite");
		}finally{
			if(br != null){
				br.close();
			}
		}
	}
}

「ポイント解説」
Javaのファイルの読み書きの心得のある人なら全く問題はないであろう。ファイルの内容を1行ずつListに詰めてそれをリクエストスコープに詰めているだけだ。ただ、memo.txtを未作成でここにアクセスするとFileNotFoundExceptionが発生するのでその場合はFileWriteに転送する処理を加えている

9.FileReadのviewを作成しよう。WEB-INF/view/の中にfileread.jspを作成する。
●fileread.jsp(WEB-INF/view/fileread.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%
List<String> lines=(List<String>)request.getAttribute("lines");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Joytas10</title>
</head>
<body>
<a href="/joytas10/FileWrite">書く</a>
<%if(lines != null && lines.size() > 0) {%>
<ul>
<%for(String line:lines){ %>
<li><%=line %></li>
<%} %>
</ul>
<%} %>

</body>
</html>

10.最後にcontroller.FileWrite.javaのリダイレクト先をFileReadに変更しよう。(パスをシスアウトしている部分もコメントにする)
●controller.FileWrite.java

package controller;

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.RequestDispatcher;
import javax.servlet.ServletContext;
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("/FileWrite")
public class FileWrite extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/view/filewrite.jsp");
		rd.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String memo=request.getParameter("memo");
		ServletContext application=this.getServletContext();
		String path=application.getRealPath("/WEB-INF/data/memo.txt");
		//System.out.println(path);
		FileOutputStream fos=new FileOutputStream(path,true);
		OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
		BufferedWriter bw=new BufferedWriter(osw);
		Date now=new Date();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String date=sdf.format(now);
		bw.write(date);
		bw.write("\t");
		bw.write(memo);
		bw.newLine();
		bw.close();
		//response.sendRedirect("/joytas10/FileWrite");	
		response.sendRedirect("/joytas10/FileRead");	
	}
}

以上で基本的なファイルの読み書きは終了だ。店長からの一言をWeb上から更新できるようにしたり、ファイル情報をもとにDBに書き込んだりとファイルの読み書きは出番が多い。繰り返し練習してしっかりと身につけよう。