HTTP のメッセージ作成

HTTP のメッセージを作るプログラムを示します。 クラスはエラーコードの含まれている Status と、メッセージ作成用のクラス Message, そのサブクラスである FileContent と ErrorMessage クラスです。 なお、テスト用のクラスを以下に示します。


/**
 * テスト用クラス
 */
class Test {
    public static void main(String[] arg)
	throws IOException {
	Message m = Message.getInstance(arg[0]);
	System.out.println(m);
    }
}

Status


import java.util.HashMap;
/**
 * ステータスコードを管理する
 */
class Status {
/** プライベートなコンストラクタ
* オブジェクト作成の禁止
*/
    private Status(){}
/** ステータス行用の言葉のデータベース
 */  
    private static HashMap<Integer,String> word;
/** ボディ用のメッセージのデータベース
 */  
    private static HashMap<Integer,String> message;
/** ステータス行用の言葉の初期化
 */
    private static void initializeWord(){
	word = new HashMap<Integer,String>();
	word.put(200,"Ok");
	word.put(404,"Not Found");
    }	
/** ステータス行用の言葉を返す
 * @param ステータスコード
 * @return ステータス行用の言葉
 */
    public static String getWord(int statusCode){
	if(word==null){
	    initializeWord();
	}
	return word.get(statusCode);
    }
/** ボディ用のメッセージの初期化
 */
    private static void initializeMessage(){
	message = new HashMap<Integer,String>();
	message.put(404,"Not Found");
    }
/** ボディ用のメッセージを返す。
 * @param ステータスコード
 * @return ボディ用のメッセージ
 */
    public static String getMessage(int statusCode){
	if(message==null){
	    initializeMessage();
	}
	return message.get(statusCode);
    }
}

Message


import java.io.*;
import java.util.*;
/** メッセージを作成する。
 * 最終的に abstract メソッドが無くなったが、このクラスはインスタンス
 * 化しない
 */
abstract class Message {
/** インスタンス化できないようにデフォルトコンストラクタは
 *   private にしておく
 */
    private Message(){}
/** メッセージを作るファクトリ
 * @param ファイル名
 * @returns FileContent あるいは ErrorMessge のインスタンス
 * @throws IOException
 */
    public static Message getInstance(String filePath)
    throws IOException {
	File f = new File(filePath);
	Message message;
	try {
	    message = new FileContent(f);
	}catch(FileNotFoundException e) {
	    message = new ErrorMessage(404);
	}
	return message;
    }
/** メッセージを作成するテンプレート
 * @returns 全メッセージ
 */
    @Override public String toString(){
	return getStatusLine()+"\n"+getHeader()+"\n"+getBody();
    }
/** ステータス行を作るテンプレート
 * @return ステータス行
 */
    private String getStatusLine(){
	return "HTTP/1.0 "+getStatusCode()+" "
	    +Status.getWord(getStatusCode());
    }
/** ヘッダを作るテンプレート
 * @return ヘッダ
 */
    private String getHeader(){
	StringWriter sw = new StringWriter();
	PrintWriter pw = new PrintWriter(sw);
	pw.println("Content-Type: text/plain; charset=shift_jis");
	pw.println("Date: "+getDate());
	pw.println("Content-Length: "+getBody().length());
	pw.close();
	return sw.toString();
    }
    protected int errorCode;
    protected Date date;
    protected String body;
/** @return ステータスコード
*/
    public int getStatusCode(){
	return errorCode;
    }
/** 日付を文字列で返す
 * @return 日付の文字列表現
 */
    public String getDate(){
	return date.toString();
    }
/** ボディを返す
 * @return ボディ
 */
    public String getBody(){
	return body;
    }
}

FileContent


import java.io.*;
import java.util.*;
/** ファイルを読み込みメッセージを作成する
 */
class FileContent extends Message {
    private FileContent(){}
/** ファイル名を受け取るコンストラクタ
 * @param ファイル名
 */
    protected FileContent(File f) 
	throws FileNotFoundException, IOException {
	super();
	FileInputStream fis = new FileInputStream(f);
	CharArrayWriter caw = new CharArrayWriter();
	int data;
	while((data = fis.read())!=-1){
	    caw.write(data);
	}
	body = caw.toString();
	date = new Date(f.lastModified());
	errorCode = 200;
    }
}

ErrorMessage


import java.io.*;
import java.util.*;
/** エラーメッセージを作成する
 */
class ErrorMessage extends Message {
    private ErrorMessage(){}
/** ステータスコードを受け取るコンストラクタ
 * @param ステータスコード
 */
    protected ErrorMessage(int errorCode){
	super();
	this.errorCode = errorCode;
	body = Status.getMessage(errorCode);
	date = new Date();
    }
}