Servlet日記(1999/04/03)

本日の成果

 前回のservletをさらに改造して、すでに入力してあるデータを削除できるようにしました。

 前回は番号をリンクにしていましたが、今回はそれをやめ、番号の横にそのメッセージに対する操作のリンクを表示するようにしました。操作はreplyとdeleteで、それぞれそのメッセージへの応答の入力、そのメッセージの削除を行います。replyの動作は、前回と同じです。deleteでそのメッセージを削除すると、その後のメッセージを詰めて表示します。メッセージの番号は付け変わりません。削除したメッセージの番号は欠番になります。

 reply, deleteのためのメッセージ番号は、QueryStringでURLに埋め込んであります。今回は操作が2種類あるので、URLにコマンドも埋め込んでいます。doGet()メソッドでコマンドを取り出し、コマンドが指定されていればメッセージ番号を取り出し、指定されたメッセージに対して操作を行っています。前回からあちこち変更したので、ソースコードを全部示します。

import  java.io.*;
import  java.util.*;
import  javax.servlet.*;
import  javax.servlet.http.*;

class BbsMsg {
    private static BbsMsg top = null;
    private static BbsMsg tail = null;
    private static int nextMsgNo = 1;

    private BbsMsg next;
    private int msgNo;
    private String msgName;
    private String msgSubject;
    private String msgContent;
    private Date msgDate;

    public BbsMsg() {
        appendMsg(this);
        msgNo = getNextMsgNo();
        msgName = null;
        msgSubject = null;
        msgContent = null;
        msgDate = new Date();
    }

    public BbsMsg(String nam, String subj, String cont) {
        this();
        setName(nam);
        setSubject(subj);
        setContent(cont);
    }

    private static void appendMsg(BbsMsg msg) {
        msg.next = null;
        if (top == null) {
            top = msg;
            tail = msg;
        } else {
            tail.next = msg;
            tail = msg;
        }
    }

    private static int getNextMsgNo() {
        return nextMsgNo++;
    }

    public static void deleteMsg(int msgNo) {
        BbsMsg msg, prevMsg;

        for (prevMsg = null, msg = top; msg != null; prevMsg = msg, msg = msg.next) {
            if (msg.getMsgNo() == msgNo) {
                if (msg == top) {
                    if (msg == tail) {
                        top = null;
                        tail = null;
                    } else {
                        top = msg.next;
                    }
                } else if (msg == tail) {
                    prevMsg.next = null;
                    tail = prevMsg;
                } else {
                    prevMsg.next = msg.next;
                }
                break;
            }
        }
    }

    public static BbsMsg getNextMsg(BbsMsg msg) {
        if (msg == null)
            return top;
        else
            return msg.next;
    }

    public static BbsMsg getMsg(int msgNo) {
        BbsMsg msg;

        for (msg = top; msg != null; msg = msg.next) {
            if (msg.getMsgNo() == msgNo)
                break;
        }
        return msg;
    }

    public String getName() {
        return msgName;
    }
    public void setName(String nam) {
        msgName = nam;
    }
    public String getSubject() {
        return msgSubject;
    }
    public void setSubject(String subj) {
        msgSubject = subj;
    }
    public String getContent() {
        return msgContent;
    }
    public void setContent(String cont) {
        msgContent = cont;
    }
    public Date getDate() {
        return msgDate;
    }
    public int getMsgNo() {
        return msgNo;
    }
}

public class Bbs03 extends HttpServlet {
    public void doGet(
        HttpServletRequest req,
        HttpServletResponse res
    ) throws ServletException, IOException
    {
        String cmd = req.getParameter("cmd");
        String msgNoStr = req.getParameter("msgno");
        String url;
        BbsMsg msg;
        BbsMsg refMsg;

        refMsg = null;
        if ("delete".equals(cmd))
            BbsMsg.deleteMsg(Integer.parseInt(msgNoStr));
        else if ("reply".equals(cmd))
            refMsg = BbsMsg.getMsg(Integer.parseInt(msgNoStr));

        res.setContentType("text/html");
        PrintWriter out = res.getWriter();
        out.println("<html><head><title>BBS Servlet Ver 0.3</title></head>");
        out.println("<body><form method=post action=\"" + req.getRequestURI() + "\">");
        out.println("<table><tr><th>name<td><input type=text name=\"uName\">");
        out.println("<tr><th>subject<td><input type=text name=\"uSubject\"");
        if ("reply".equals(cmd))
            out.println(" value=\"Re: " + refMsg.getSubject() + "\"");
        out.println(">");
        out.println("<tr><th>content<td><textarea name=\"uContent\"rows=5 cols=40>");
        if ("reply".equals(cmd))
            out.println("\n----------\n" + refMsg.getContent());
        out.println("</textarea></table>");
        out.println("<input type=submit value=\"Post\"></form><hr>");

        url = req.getRequestURI();
        for (msg = BbsMsg.getNextMsg(null); msg != null; msg = BbsMsg.getNextMsg(msg)) {
            out.println(
                "No. " + msg.getMsgNo()
              + " <a href=\"" + url + "?cmd=reply&msgno="
                      + msg.getMsgNo() + "\">reply</a>"
              + " <a href=\"" + url + "?cmd=delete&msgno="
                      + msg.getMsgNo() + "\">delete</a><br>"
              + "<dl><dt>Name:<dd>" + msg.getName()
              + "<dt>Subject:<dd>" + msg.getSubject()
              + "<dt>Date:<dd>" + msg.getDate()
              + "<dt>Content:<dd><pre>" + msg.getContent()
              + "</pre></dl><hr>"
            );
        }

        out.println("</body></html>");
        out.close();
    }

    public void doPost(
        HttpServletRequest req,
        HttpServletResponse res
    ) throws ServletException, IOException
    {
        new BbsMsg(
            req.getParameter("uName"),
            req.getParameter("uSubject"),
            req.getParameter("uContent")
        );

        doGet(req, res);
    }

    public String getServletInfo() {
        return "BBS Servlet Ver 0.3";
    }
}

本日の教訓

 "reply".equals(cmd)のように記述すると、cmd.equals("reply")のように記述するのに比べて、cmdがnullかどうか判断しなくてよいことに気づきました。定数でもオブジェクトであれば、そのメソッドが使えるのは便利です(裏側では、オブジェクトを生成するコストがかかっているのでしょうけれど)。

Servlet日記(1999/03/21) Servlet日記の目次 Servlet日記(1999/04/25)