次の授業が始まるまで時間があったので、研究室のパソコンでWicketを使ったプログラムを作ってみた。ここ数週間やる気が全くでなくて困っていたが、ちょっとやる気が復活してきたかもしれない。作ってみたのは一言掲示板で、WicketのexamplesにあったGuestBookに名前欄とファイルに保存昨日を加えたようなもの。要Java 1.6。まずはHTMLから
LineBoardPage.html
<html> <head> <title>一言掲示板</title> </head> <body> <div wicket:id="feedback">エラーメッセージ</div> <form wicket:id="inputForm"> 名前:<input type="text" wicket:id="inputName" /><br /> 内容:<input type="text" wicket:id="inputMessage" /><br /> <input type="submit" value="書き込む" wicket:id="submit"/> </form> <hr> <dl wicket:id="lineList"> <dt> 名前:<span wicket:id="name">d-kami</span> <span wicket:id="date">2008/04/24</span> </dt> <dd wicket:id="message">一行コメント</dd> </dl> </body> </html>
上のHTMLに対応したWebPage、LineBoardPage.java
package lineboard; import java.io.File; import java.io.FileOutputStream; import java.util.List; import java.util.ArrayList; import java.util.Date; import java.text.SimpleDateFormat; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.model.Model; import org.apache.wicket.model.LoadableDetachableModel; public class LineBoardPage extends WebPage{ public LineBoardPage(){ //書き込み保存用のファイルのパスを求める String path = ((WebApplication)this.getApplication()).getServletContext().getRealPath("comment.xml"); final File file = new File(path); //エラーメッセージ表示 FeedbackPanel feedback = new FeedbackPanel("feedback"); add(feedback); //フォームの構築 Form form = new Form("inputForm"); final TextField nameField = new TextField("inputName", new Model()); final TextField messageField = new TextField("inputMessage", new Model()); Button submitButton = new Button("submit"){ @Override public void onSubmit(){ String name = nameField.getModelObjectAsString(); String message = messageField.getModelObjectAsString(); Comment comment = new Comment(name, message); synchronized(LineBoardPage.this){ //過去に書き込まれたコメントを読み込む CommentList commentList = readCommentList(file); //書き込まれた内容を追加してXML形式で保存 commentList.addComment(name, message); writeCommentList(commentList, file); } } }; form.add(nameField); form.add(messageField); form.add(submitButton); add(form); LoadableDetachableModel model = new LoadableDetachableModel(){ @Override protected Object load(){ CommentList commentList = null; synchronized(LineBoardPage.this){ commentList = readCommentList(file); } return commentList.getCommentList(); } }; //コメントを表示するListView ListView lineListView = new ListView("lineList", model){ @Override protected void populateItem(ListItem item){ Comment comment = (Comment)item.getModelObject(); item.add(new Label("name", comment.getName())); item.add(new Label("date", comment.getDate())); item.add(new Label("message", comment.getMessage())); nameField.setModelObject(""); messageField.setModelObject(""); } }; add(lineListView); } //XML形式のfileからCommentListを読み込む private CommentList readCommentList(File file){ CommentList commentList; try{ JAXBContext context = JAXBContext.newInstance(CommentList.class); Unmarshaller unmarshaller = context.createUnmarshaller(); commentList = (CommentList)unmarshaller.unmarshal(file); }catch(Exception e){ e.printStackTrace(); //例外がでたら新しいコメントリストを作る commentList = new CommentList(); } return commentList; } //fileにCommentListをXML形式で書き込む private void writeCommentList(CommentList commentList, File file){ try{ JAXBContext context = JAXBContext.newInstance(CommentList.class); Marshaller marshaller = context.createMarshaller(); marshaller.marshal(commentList, new FileOutputStream(file)); }catch(Exception e){ //例外がでたらメッセージを表示 error(e); e.printStackTrace(); } } //Commentのリストを格納する暮らす @XmlRootElement(name="CommentList") static class CommentList{ @XmlElement(name="Comment") private List<Comment> list; public CommentList(){ list = new ArrayList<Comment>(); } public List<Comment> getCommentList(){ return new ArrayList(list); } public void addComment(String name, String message){ list.add(0, new Comment(name, message)); } } //コメントを表すクラス @XmlRootElement(name="Comment") static class Comment{ @XmlElement(name="Name") private String name; @XmlElement(name="message") private String message; @XmlElement(name="date") private String date; public Comment(String name, String message){ this.name = name; this.message = message; //日付はコンストラクタを呼び出した時刻にする SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm"); this.date = format.format(new Date()); } //JAXB用のコンストラクタ private Comment(){ } public String getName(){ return this.name; } public String getMessage(){ return this.message; } public String getDate(){ return this.date; } }
アプリケーションクラス、LineBoardApplication.java
package lineboard; import org.apache.wicket.protocol.http.WebApplication; public class LineBoardApplication extends WebApplication{ @Override public Class getHomePage(){ return LineBoardPage.class; } }
<filter> <filter-name>LineBoard</filter-name> <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class> <init-param> <param-name>applicationClassName</param-name> <param-value>lineboard.LineBoardApplication</param-value> </init-param> </filter> <filter-mapping> <filter-name>LineBoard</filter-name> <url-pattern>/LineBoard/*</url-pattern> </filter-mapping>