総合政策学部4年 伊藤玲子 総合政策学部4年 阿部雅美 +CreWな皆様 投稿を保存しよう! 総合政策学部4年 伊藤玲子 総合政策学部4年 阿部雅美 +CreWな皆様
今日の目標 WebApplicationにおいて、ファイルを用いたデータの保存ができるようになる 保存することの意味がわかるようになる ストリームの使い方がわかるようになる
前回までの復習 WEBアプリにとは何だ~!! ★人を幸せにするコンセプトをもっている★
「サブゼミ疑問解決掲示板」のコンセプトを思い出そう コンセプト: 授業外で生じた疑問をみんなで共有・解決し、 授業の理解を深めて、よりよいサブゼミにする。 概要: 授業外で生じた疑問を質問として掲示板に 投稿。投稿者の疑問を解決できると思う人が 回答を投稿する。 疑問を解決したい(投稿) 質問と回答をみんなで共有して理解を深めたい(閲覧) →先週作った掲示板はどんなだった…??
現行「サブゼミ疑問解決掲示板」の深刻な問題 自分が投稿した質問を自分で見るだけ 過去に投稿された質問を見ることができない 実は掲示板じゃなかった!!!
どうしよう? 質問をみんなが見れるようにしよう 投稿された質問を保存できるようにしよう 今回は「ファイル」に保存することで実現します 他にもやりかたはありますがそれはまた今度
2つのサーブレット 役割分担 質問を投稿する → ToukouServlet.java 質問の投稿を受け付ける 受け付けた質問をファイルに書き込む 感謝のメッセージのHTMLを出力する 質問を一覧表示する→IchiranServlet.java 質問をファイルから読み出す 質問一覧のHTMLを出力する 投稿サーブレット 書き込み ファイル 一覧サーブレット 読み込み
新・サブゼミ疑問解決掲示板の構成 GimonKaiketu-Web WEB-INF classes ToukouServlet.class 質問投稿サーブレット GimonKaiketu-Web 質問一覧サーブレット WEB-INF classes ToukouServlet.class IchiranServlet.class lib 質問保存ファイル text question.txt web.xml 投稿フォーム画面 html toukou.html index.html サブゼミ疑問解決掲示板トップページ
ファイルの保存編
何を保存しよう 疑問解決掲示板で保存したいものを考えてみよう! 質問 投稿した人の名前 日付 時間 番号 …etc
適切な名前を考えよう 例えば… 質問? 投稿者名 投稿日時 タイトル 質問 投稿者名 投稿日時 タイトル 内容
どのように記録する? サブゼミ疑問解決掲示板では 投稿者名 タイトル 投稿日時 内容 をそれぞれ1行ずつ 杉浦学┓ 投稿者名 タイトル 投稿日時 内容 をそれぞれ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形式のとおりファイルを読み込むから
書き込み編
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); content = convertReturnCode(content); title = convertReturnCode(title); //ファイルに書き込むためのストリームを作成する BufferedWriter writer = new BufferedWriter( new FileWriter(recipeFilePath, true) ); //このtrueはファイルへの追記を意味する //受け取ったメッセージを、contributor, title, date, content の順で書き込む writer.write(contributor); writer.newLine(); writer.write(title); writer.write(date); writer.write(content); //ストリームを閉じる writer.close(); //***** 感謝のメッセージのHTMLを出力する ***** //HTML出力の準備をする PrintWriter out = response.getWriter(); //HTMLの出力に必要なPrintWriterを作成する out.println("<html>"); //感謝のHTMLを出力する out.println("<head><title>投稿ありがとうございました!</title></head>"); out.println("<body bgcolor='#33CCFF' text='#000000'>"); out.println("<font size='big'><b>投稿ありがとうございました!"); out.println("[ <a href=\"IchiranServlet\">サブゼミ疑問だらけコーナーへ</a> ]"); out.println("<br>また何かわからないことがあったら投稿してね。</b></font><br><br>"); 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.write(date); writer.write(content); //ストリームを閉じる writer.close(); 今日のポイント
ストリームのお話1 入出力先にはいろいろある 入出力データもいろいろある これらを扱うのに, いちいち場合分けしていたら大変! (キーボード,ネットワーク,ディスプレイ…) 入出力データもいろいろある (バイト列,文字列,オブジェクト…) これらを扱うのに, いちいち場合分けしていたら大変!
ストリームのお話2 例えば… 入出力先にはいろいろなものがあるので これらをまとめて全部入出力先として扱えると便利 入出力先! ・ 入出力先! キーボード ファイル ディスプレイ ネットワーク ・
ストリームのお話3 ストリームはさまざまな入出力を抽象化して 「データの流れ」として扱い,簡単にデータへのアクセスができるようにしたもの 「データの流れ」として扱い,簡単にデータへのアクセスができるようにしたもの 入力 出力 ファイル ファイル < H T M L > < H T M L > ストリーム! プログラム G E T t o u ネットワーク ネットワーク G E T t o u エ ラ ー が 起 こ り こ ん に ち は 。 \n ディスプレイ キーボード ・ ・
ストリームの特徴 ストリームとはデータの流れである 例えば… (疑問解決掲示板の例) 先頭から順番に送られて、順番に受け取る データの意味は認識してない 順番だけで構造はない 例えば… (疑問解決掲示板の例) 疑問解決 掲示板 サーブレット 質問ファイル ん な は 言 宣 頭 冒
ストリームの種類 文字列(アスキー) 文字列以外(バイナリ) 質問ファイル 疑問解決 掲示板 サーブレット ん な は 言 宣 頭 冒 ペイントソフト 画像ファイル 0xEF 0xC2 0x4B 0x24 0x8C 0xD3 0x33
ここで使うストリーム 今回は、 文字列を、 ファイルに 保存しよう。 使うもの import java.io.*; 今回は、 文字列を、 ファイルに 保存しよう。 使うもの 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.write(date); writer.write(content); //ストリームを閉じる 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>"); 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.write(date); writer.write(content); 読み込み時 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 インデックス(案内とリンク) toukou.html 投稿フォーム画面 ToukouServlet.java 質問投稿サーブレット IchiranServlet.java 質問一覧サーブレット question.txt 質問保存ファイル