JSTLを酷使して掲示板を作る
ちょっとJavaで掲示板みたいの作ってみた。
構成
ファイル名称 Java_BBS ├──.classpath ├──build │ └──classes │ └──http │ └──bbs │ └──main │ ├──MainBBSServlet.class │ ├──PostedSentence.class │ └──SetCharacterEncodingFilter.class ├──src │ └──http │ └──bbs │ └──main │ ├──MainBBSServlet.java │ ├──PostedSentence.java │ └──SetCharacterEncodingFilter.java … たぶんeclipse使ってWEBアプリ作ろうとすると必ずぶち当たる文字化け問題。それを解決してくれるソース。 └──WebContent ├──css │ └──bbs.css ├──img │ └──kabegami14.jpg ├──index.jsp ├──META-INF │ └──MANIFEST.MF └──WEB-INF ├──data ├──lib │ ├──commons-lang3-3.0.1.jar │ ├──commons-lang3-3.0.1-tests.jar │ ├──jstl.jar │ └──standard.jar └──web.xml
SetCharacterEncodingについては以下のサイトが詳しい。というかJavaの道さんとJSTLリファレンスのサイトにはかなりお世話になっています。
Javaの道:Struts(8.アクション・フォームBeanの日本語処理)
サーブレットのソースは以下
package http.bbs.main; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import org.apache.commons.lang3.RandomStringUtils; /** * MainBBSServlet 掲示板の制御を行うクラス * * @author Nantonaku-Shiawase 2011/10/22 Javaの練習用に作成 ver 1.0 */ @SuppressWarnings("serial") public class MainBBSServlet extends HttpServlet { final static String FILE_PATH = "WEB-INF/data/bbs.dat"; private List<PostedSentence> chatList; // サーブレット初期化の際に今まで書きこまれた投稿のデータを読み込む public void init() throws ServletException { chatList = new Vector<PostedSentence>(); File file = getDataFile(); if ( file.exists()) { try { InputStream in = new FileInputStream(file); XMLDecoder decoder = new XMLDecoder(in); chatList = (List<PostedSentence>) decoder.readObject(); decoder.close(); } catch ( FileNotFoundException e) { throw new ServletException(e); } } } // doGetは必ずいるんです public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { doPost(req, res); } // メインのPostメソッド public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html; charset=windows-31j"); if (req.getParameter("sentence").isEmpty()) { // 本文に何も入っていいなければ門前払い RequestDispatcher dispatcher = req.getRequestDispatcher("index.jsp"); dispatcher.forward(req, res); } else { // 投稿された内容を納めるクラス PostedSentence ps = new PostedSentence(); // 一つ目の要素は名前 if ( req.getParameter("name").isEmpty() ) { ps.add("名無しさん@涙目です"); } else { ps.add(req.getParameter("name")); } // 2つめの要素はメール欄 if ( req.getParameter("mail").isEmpty() ) { ps.add("[]"); } else { ps.add("[" + req.getParameter("mail") + "]"); } // 3つめは時間 ps.add(getTime()); // 4つめはID ps.add("ID:" + getID()); // 5つめは本文 ps.add(req.getParameter("sentence")); // 6・7は記録用…ユーザーエージェントとIPアドレス ps.add(req.getHeader("user-agent")); ps.add(req.getRemoteAddr()); chatList.add(ps); // アプリケーションスコープでデータを拾えるように設定 ServletContext application = getServletContext(); application.setAttribute("chatList", chatList); // 掲示板のインデックスページに転送 RequestDispatcher dispatcher = req.getRequestDispatcher("index.jsp"); dispatcher.forward(req, res); }// 長いelse文になってしまった } public void destroy () { File file = getDataFile(); try { OutputStream out = new FileOutputStream(file); XMLEncoder encoder = new XMLEncoder(out); encoder.writeObject(chatList); encoder.close(); } catch ( IOException e) { e.printStackTrace(); } } // ファイルのパスを確認してオブジェクトで返すメソッド private File getDataFile() { String path = getServletContext().getRealPath(FILE_PATH); return new File(path); } // 投稿日を取得するメソッド private String getTime() { Calendar cal = Calendar.getInstance(); int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DATE); int hour = cal.get(Calendar.HOUR_OF_DAY); int minute = cal.get(Calendar.MINUTE); int second = cal.get(Calendar.SECOND); StringBuffer dow = new StringBuffer(); switch (cal.get(Calendar.DAY_OF_WEEK)) { case Calendar.SUNDAY: dow.append("日"); break; case Calendar.MONDAY: dow.append("月"); break; case Calendar.TUESDAY: dow.append("火"); break; case Calendar.WEDNESDAY: dow.append("水"); break; case Calendar.THURSDAY: dow.append("木"); break; case Calendar.FRIDAY: dow.append("金"); break; case Calendar.SATURDAY: dow.append("土"); break; } return ("投稿日:" + year + "/" + month + "/" + day + " (" + dow + ") " + hour + ":" + minute + ":" + second); } // ランダムなIDを取得して返すメソッド private String getID () { RandomStringUtils rs = new RandomStringUtils(); return rs.random(9,"0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM+/"); } }
そして問題のJSPファイルは以下
<%@ page language="java" contentType="text/html; charset=windows-31j" pageEncoding="windows-31j"%> <%@ page import="java.util.*" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <jsp:useBean id="bean" class="http.bbs.main.MainBBSServlet" scope="application"/> <c:set var="chatList" value="${ chatList }" scope="application" property="List" /> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-31j"> <link rel="stylesheet" href="css/bbs.css" type="text/css"> <title>掲示板トップ</title> </head> <body background="img/kabegami14.jpg"> <!-- 全体を中央寄せにします --> <div id="wrapper"> <h2>掲示板トップ</h2> <div class="formbox"><form action="<%= request.getContextPath() %>/MainBBSServlet" method="post" id="BBSform"> 名前: <input type="text" name="name"> メール: <input type="text" name="mail"><br><br> 本文: <input type="text" name="sentence" style="height: 90px; width: 450px"> <input type="submit" value="書き込み" ></input><br><br> </form></div> <div id="thread" class="bbs_box"> <h3>スレッド一覧</h3> <span><a href="http://www.google.com">http://www.google.com</a></span><br> <span>ダミーですが何か?</span><br> </div> <div id="postedcontent" class="formbox"> <table> <c:forEach var="objParent" items="${chatList}" varStatus="sttParent"> <table> <tr id="<c:out value="${sttParent.index}"/>"> <c:forEach begin="0" end="4" step="1" var="objChild" items="${objParent}" varStatus="sttChild"> <c:if test="${sttChild.index == 4}"><tr></c:if> <td><c:if test="${sttChild.index == 0}"><c:out value="${sttParent.index +1 }"/>:</c:if><c:out value="${objChild}"/> <c:if test="${sttChild.index == 4}"></tr></c:if> </c:forEach> </tr> </table> </c:forEach> </table> </div> </div> </body> </html>
- ポイント
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
この部分でクラスとスコープを宣言して書き込みのリストを拾えるようにしておく
そして読み手無視のJSTLw
<c:forEach var="objParent" items="${chatList}" varStatus="sttParent"> ← 入れ子になったリストを取り出す <table> <tr id="<c:out value="${sttParent.index}"/>"> <c:forEach begin="0" end="4" step="1" var="objChild" items="${objParent}" varStatus="sttChild"> ← オブジェクトの5,6番目はユーザーに見せない <c:if test="${sttChild.index == 4}"><tr></c:if> <td><c:if test="${sttChild.index == 0}"><c:out value="${sttParent.index +1 }"/>:</c:if><c:out value="${objChild}"/> <c:if test="${sttChild.index == 4}"></tr></c:if> </c:forEach> </tr> </table> </c:forEach>
この本はよかった。ありがてえ。
基礎からのサーブレット/JSP 改訂版 (プログラマの種シリーズ)
- 作者: 宮本信二
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2007/03/01
- メディア: 単行本
- 購入: 4人 クリック: 57回
- この商品を含むブログ (15件) を見る
次はPerlで同じ物をつくりたいですなあ。