掲示板メッセージを保存する

投稿を保存しよう!
総合政策学部4年 伊藤玲子
総合政策学部4年 阿部雅美
+CreWな皆様
今日の目標

WebApplicationにおいて、ファイルを用い
たデータの保存ができるようになる
保存することの意味がわかるようになる
 ストリームの使い方がわかるようになる

前回までの復習

WEBアプリにとは何だ~!!
★人を幸せにするコンセプトをもっている★
「サブゼミ疑問解決掲示板」のコン
セプトを思い出そう
コンセプト: 授業外で生じた疑問をみんなで共有・解決し、
授業の理解を深めて、よりよいサブゼミにする。
概要: 授業外で生じた疑問を質問として掲示板に
投稿。投稿者の疑問を解決できると思う人が
回答を投稿する。
•疑問を解決したい(投稿)
•質問と回答をみんなで共有して理解を深めたい(閲
覧)
→先週作った掲示板はどんなだった…??
現行「サブゼミ疑問解決掲示板」の
深刻な問題
自分が投稿した質問を自分で見るだけ
 過去に投稿された質問を見ることができない

実は掲示板じゃなかった!!!
どうしよう?
質問をみんなが見れるようにしよう
 投稿された質問を保存できるようにしよう


今回は「ファイル」に保存することで実現します
• 他にもやりかたはありますがそれはまた今度
2つのサーブレット
役割分担

質問を投稿する → ToukouServlet.java




質問の投稿を受け付ける
受け付けた質問をファイルに書き込む
感謝のメッセージのHTMLを出力する
質問を一覧表示する→IchiranServlet.java


質問をファイルから読み出す
質問一覧のHTMLを出力する
投稿サーブレット
ファイル
一覧サーブレット
新・サブゼミ疑問解決掲示板の構成
質問投稿サーブレット
GimonKaiketu-Web
質問一覧サーブレット
WEB-INF
classes
ToukouServlet.class
lib
IchiranServlet.class
text
question.txt
質問保存ファイル
web.xml
html
index.html
toukou.html
投稿フォーム画面
サブゼミ疑問解決掲示板
トップページ
ファイルの保存編
何を保存しよう

疑問解決掲示板で保存したいものを考えて
みよう!
質問
 投稿した人の名前
 日付
 時間
 番号
 …etc

適切な名前を考えよう
例えば…
 質問?




投稿者名
投稿日時
タイトル
質問?

質問
投稿者名
 投稿日時
 タイトル
 内容

どのように記録する?

サブゼミ疑問解決掲示板では
投稿者名
タイトル
投稿日時
内容
をそれぞれ1行ずつ
杉浦学┓
web.xmlの冒頭宣言┓
Wed May 23 17:30:24 JST 2002 ┓
Web.xmlの冒頭宣言はなんであんなに長いんで… ┓
杉浦学┓
タッチタイピング┓
Wed May 23 17:34:11 JST 2002 ┓
タッチタイピングができません!いったいどうし… ┓
O岩元┓
Re:タッチタイピング┓
Wed May 23 17:36:02 JST 2002 ┓
それは困りましたね… ┓
ファイル形式

ファイル形式とは?
• 何を保存するか
• どんな順番で保存するか etc
「保存」の機能を作るには
ファイル形式を自分たちで決める必要があります
ファイル形式の例

Wordのファイル形式(.doc)
Word形式でファイルを書き込み、
 Word形式のとおりファイルを読み込むから
 Word形式を知らないとdocファイルは扱えない

書き込み編
ToukouServlet.java:doPost()
/**
* doPost() メソッドは、POSTリクエストがブラウザー
* からプログラムに発信されたときに呼び出されるメソッド
**/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
/**
* HTMLフォームからのメッセージを受け取る前に、
* メッセージのエンコーディングを指定して文字化けを防ぐ。
**/
request.setCharacterEncoding("Shift_JIS");
//HTTPリクエストのパラメータからメッセージを取り出す
String contributor = request.getParameter("contributor");
String title = request.getParameter("title");
String content = request.getParameter("content");
←質問の投稿を受け付ける
//投稿された時刻を取得する
String date = (new java.util.Date()).toString();
//*****受け取ったメッセージをファイルに保存する*****
//改行を正しい形に変換する
//(改行コードが含まれると、書き込んだ際、1行に収まらなくなってしまう)
contributor = convertReturnCode(contributor);
title = convertReturnCode(title);
content = convertReturnCode(content);
//ファイルに書き込むためのストリームを作成する
BufferedWriter writer = new BufferedWriter( new FileWriter(recipeFilePath, true) ); //このtrueはファイルへの追記を意味する
//受け取ったメッセージを、contributor, title, date, content の順で書き込む
writer.write(contributor);
writer.newLine();
writer.write(title);
writer.newLine();
writer.write(date);
writer.newLine();
writer.write(content);
writer.newLine();
←受け付けた質問をファイルに書き込む
//ストリームを閉じる
writer.close();
//***** 感謝のメッセージのHTMLを出力する *****
//HTML出力の準備をする
PrintWriter out = response.getWriter(); //HTMLの出力に必要なPrintWriterを作成する
//感謝のHTMLを出力する
out.println("<html>");
out.println("<head><title>投稿ありがとうございました!</title></head>");
out.println("<body bgcolor='#33CCFF' text='#000000'>");
out.println("<font size='big'><b>投稿ありがとうございました!");
out.println("<br>また何かわからないことがあったら投稿してね。</b></font><br><br>");
out.println("[ <a href=\"IchiranServlet\">サブゼミ疑問だらけコーナーへ</a> ]");
out.println("</body>");
out.println("</html>");
//HTML出力のあとかたづけをする
out.close();
}
←感謝のメッセージのHTMLを出力する
質問の投稿を受け付ける
//***** 質問の投稿を受け付ける *****
//HTTPリクエストのパラメータから、質問を構成する情報を取り出す
String contributor = request.getParameter("contributor"); //投稿者
String title = request.getParameter("title"); //タイトル
String content = request.getParameter(“content”); //質問内容
//投稿された時刻を取得する
String date = (new java.util.Date()).toString();
受け付けた質問を
ファイルに書き込む
//***** 受け付けた質問をファイルに書き込む *****
//改行を正しい形に変換する
//(改行コードが含まれると、書き込んだ際、1行に収まらなくなってしまう)
contributor = convertReturnCode(contributor);
title = convertReturnCode(title);
content = convertReturnCode(content);
//ファイルに書き込むためのストリームを作成する
BufferedWriter writer = new BufferedWriter( new FileWriter(recipeFilePath, true) ); //このtrueはファイルへの追記を意味する
//質問を、contributor, title, date, content の順で書き込む
writer.write(contributor);
writer.newLine();
writer.write(title);
writer.newLine();
writer.write(date);
writer.newLine();
writer.write(content);
writer.newLine();
//ストリームを閉じる
writer.close();
今日のポイント
ストリームのお話1
入出力先にはいろいろある
 (キーボード,ネットワーク,ディスプレイ…)
入出力データもいろいろある
 (バイト列,文字列,オブジェクト…)
これらを扱うのに,
いちいち場合分けしていたら大変!
ストリームのお話2
例えば…
入出力先にはいろいろなものがあるので
これらをまとめて全部入出力先として扱えると便利
キーボード
ファイル
ディスプレイ
ネットワーク
・
・
・
入出力先!
ストリームのお話3

ストリームはさまざまな入出力を抽象化して
「データの流れ」として扱い,簡単にデータへのアク
セスができるようにしたもの
入力
出力
ファイル
ファイル
ネットワーク
u o t
T E G
プログラム
u o t
T E G
ネットワーク
キーボード
ディスプレイ
・
・
・
・
・
・
ストリーム!
ストリームの特徴

ストリームとはデータの流れである

先頭から順番に送られて、順番に受け取る
• データの意味は認識してない
• 順番だけで構造はない

例えば… (疑問解決掲示板の例)
疑問解決
掲示板
サーブレット
ん な は 言 宣 頭 冒
質問ファイル
ストリームの種類

文字列(アスキー)
疑問解決
掲示板
サーブレット

ん な は 言 宣 頭 冒
質問ファイル
文字列以外(バイナリ)
ペイントソフト
0x33 0xD3 0x8C 0x24 0x4B 0xC2 0xEF
画像ファイル
ここで使うストリーム
今回は、
文字列を、
ファイルに
保存しよう。
 使うもの import java.io.*;


文字列をファイルに保存する
• FileReader, FileWriter

バッファリング機能を付加する
• BufferedReader, BufferedWriter
おまけ的解説
//ファイルに書き込むためのストリームを作成する
FileWriter fileWriter = new FileWriter(recipeFilePath, true);
BufferedWriter writer = new BufferedWriter(fileWriter);
FileWriterだけで保存することはできますが、
それだけだと効率が悪いのでBufferedWriterも一緒に使ってあげましょう
(詳しくはjava api ドキュメントのBufferedWriterクラスのところ参照)
(さらに詳しくは中鉢さんをつかまえよう!)
受け付けた質問をファイルに書き込む
//***** 受け付けた質問をファイルに書き込む *****
//改行を正しい形に変換する
//(改行コードが含まれると、書き込んだ際、1行に収まらなくなってしまう)
contributor = convertReturnCode(contributor);
title = convertReturnCode(title);
content = convertReturnCode(content);
//ファイルに書き込むためのストリームを作成する
BufferedWriter writer = new BufferedWriter( new FileWriter(questionFilePath, true) ); //このtrueはファイルへ
//レシピを、contributor, title, date, content の順で書き込む
writer.write(contributor);
writer.newLine();
文字列を書き込む
writer.write(title);
writer.newLine();
writer.write(date);
writer.newLine();
改行文字を書き込む
writer.write(content);
writer.newLine();
//ストリームを閉じる
writer.close();
閉じるの忘れずに!
読み込み編
IchiranServlet.java: doGet()
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
//HTML出力の準備をする
request.setCharacterEncoding("Shift_JIS");//エンコーディングをして文字化けを防ぐ
PrintWriter out = response.getWriter(); //HTMLを出力するためのPrintWriterを作成する
//ページの頭部分のHTMLを出力する
out.println("<html>");
out.println("<head><title>サブゼミ疑問だらけコーナー</title></head>");
out.println("<body bgcolor=\"#33CCFF\" text=\"#000000\">");
out.println("<center><font size=5><b>疑問だらけコーナー</b></font></center>");
out.println("<hr>");
//疑問だらけ一覧のHTMLを出力する
BufferedReader reader =
new BufferedReader(new FileReader(recipeFilePath)); //ファイルを読み込むストリームを作成する
while(true) {
//contributor, title, date, content の順で読み込む
String contributor = reader.readLine();
if( contributor == null ) { //読み込めなかったらファイルの終わりなので、無限ループをぬける
break;
}
String title = reader.readLine();
String date = reader.readLine();
String content = reader.readLine();
//疑問のHTMLを出力する
out.println("<p><b><font size=4>"+contributor+"さんの疑問</font></b></p>");
out.println("<p><font size=5>「"+title+"」</font></p>");
out.println("(投稿時刻:"+ date + ")<br>");
out.println("<p>" + content + "</p>");
out.println("<hr>");
}
reader.close(); //ストリームを閉じる
//ページの尻尾部分のHTMLを出力する
out.println("</body>");
out.println("</html>");
//HTML出力のあとかたづけをする
out.close();
}
←拡大
IchiranServlet.java: doGet()
ストリームの作成
//疑問だらけ一覧のHTMLを出力する
BufferedReader reader =
new BufferedReader(new FileReader(recipeFilePath)); //ファイルを読み込むストリームを作成する
while(true) {
//contributor, title, date, content の順で読み込む
String contributor = reader.readLine();
if( contributor == null ) { //読み込めなかったらファイルの終わりなので、無限ループをぬける
break;
}
String title = reader.readLine();
String date = reader.readLine();
String content = reader.readLine();
読み込み
//疑問のHTMLを出力する
out.println("<p><b><font size=4>"+contributor+"さんの疑問</font></b></p>");
out.println("<p><font size=5>「"+title+"」</font></p>");
out.println("(投稿時刻:"+ date + ")<br>");
out.println("<p>" + content + "</p>");
out.println("<hr>");
}
reader.close(); //ストリームを閉じる
出力
ストリームを閉じる
ファイル形式を確認
書き込み時
//質問を、contributor, title, date, content の順で書き込む
writer.write(contributor);
writer.newLine();
writer.write(title);
writer.newLine();
writer.write(date);
writer.newLine();
writer.write(content);
writer.newLine();
読み込み時
while(true) {
//contributor, title, date, content の順で読み込む
String contributor = reader.readLine();
if( contributor == null ) { //読み込めなかったらファイルの終わりなので、無限ループをぬける
break;
}
String title = reader.readLine();
String date = reader.readLine();
String content = reader.readLine();
Presented by
CreW
サンプルプログラムの中身

index.html
• インデックス(案内とリンク)

toukou.html
• 投稿フォーム画面

ToukouServlet.java
• 質問投稿サーブレット

IchiranServlet.java
• 質問一覧サーブレット

question.txt
• 質問保存ファイル