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);
}
}
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);
}
}
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;
}
}
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;
}
}
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();
}
}