1

このクラスで Hastable を使用するのに問題があります。

public class HttpBuilder {
    ...        
    private int ret;
    public Hashtable headers;
    private String content;

    HttpBuilder(int majorv, int minorv, int ret){
        ver[0] = majorv;
        ver[1] = minorv;
        this.ret = ret;
        headers = new Hashtable();
    }

    ...
    public void addHeader(String header, String value){
        headers.put(header, value);
    }

    ...
}

このクラスは、複数の入力パラメータから文字列を作成します。複数のスレッドで使用します。このようなもの:

HttpBuilder Get(HttpParser request) {
    HttpBuilder response;
    String doc;
    if (request.getRequestURL().equals("/")) {
        try {
            doc = LoadDoc("main.html");
        } catch (IOException e) {
            response = new HttpBuilder(1, 1, 500);
            return response;
        }
        response = new HttpBuilder(1, 1, 200);
        response.addHeader("content-type", "text/html");
        response.setContent(doc);
    } else {
        response = new HttpBuilder(1, 1, 404);
    }
    return response;
}

addHeader Hashtable の後は空です。データを消費する:

public String toString() {
        String result;
        int len = 0;
        result = "HTTP/"+Integer.toString(ver[0])+"."+Integer.toString(ver[1])+
                " "+getHttpReply(ret)+"\n";
        if(content!=null){
            len = content.length();
            if(len!=0){
                headers.put("content-length", Integer.toString(len));
            }
        }

        Iterator it = headers.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pairs = (Map.Entry) it.next();
            result += pairs.getKey() + ": " + pairs.getValue() + "\n";
            it.remove();
        }

        if(len!=0){
            result+="\n"+content;
        }


        return result;
    }

HttpBuilder を使用するスレッド クラス

class ClientThread implements Runnable {
    private Socket socket;
    private ServerData data;
    static public final String NotImplemented = "HTTP/1.1 501 Not Implemented";
    static public final String NotFound = "HTTP/1.1 404 Not Found";

    ClientThread(Socket socket, ServerData data) {
        this.socket = socket;
        this.data = data;
    }

    @Override
    public void run() {
        try {
            HttpParser request = new HttpParser(socket.getInputStream());
            HttpBuilder response;
            if (request.parseRequest() != 200) {
                response = new HttpBuilder(1, 1, 501);
            } else {
                if (request.getMethod().equals("GET")) {
                    response = Get(request);
                } else if (request.getMethod().equals("POST")) {
                    response = Post(request);
                } else {
                    response = new HttpBuilder(1, 1, 400);
                }
            }
        } catch (IOException e) {
            Server.log.log(Level.SEVERE, e.getLocalizedMessage());
        } finally {
            try {
                socket.close();
                Server.log.log(Level.INFO, "Close connection");
            } catch (IOException e) {
                Server.log.log(Level.SEVERE, e.getLocalizedMessage());
            }
        }
    }

    void send(String response) throws IOException {
        PrintWriter out;
        out = new PrintWriter(socket.getOutputStream(), true);
        out.print(response);

    }

    String LoadDoc(String doc) throws IOException {
        final String Folder = "web" + File.separator;
        String result = null;
        doc = Folder + doc;
        long len;
        File f = new File(doc);
        FileReader fr = new FileReader(f);
        len = f.length();
        char[] buffer = new char[(int) len];
        fr.read(buffer);
        result = new String(buffer);
        fr.close();
        return result;

    }

    HttpBuilder Get(HttpParser request) {
        HttpBuilder response;
        String doc;
        if (request.getRequestURL().equals("/")) {
            try {
                doc = LoadDoc("main.html");
            } catch (IOException e) {
                response = new HttpBuilder(1, 1, 500);
                return response;
            }
            response = new HttpBuilder(1, 1, 200);
            response.addHeader("content-type", "text/html");
            response.setContent(doc);
        } else {
            response = new HttpBuilder(1, 1, 404);
        }
        return response;
    }

    HttpBuilder Post(HttpParser request) {
        HttpBuilder response;
        String str;
        if(request.getRequestURL().equals("/")){
            response = new HttpBuilder(1,1, 200);
            str = request.getContentParam("user");
            response.setContent(str+" added to the base.");
        }else {
            response = new HttpBuilder(1, 1, 404);
        }
        return response;
    }    

}
4

2 に答える 2

1

でオブジェクトを変更するのは悪い考えのようtoString()です。の目的はtoString()、オブジェクトの文字列表現を返すことです。後続の複数回の呼び出しはtoString()、同じ結果を返す必要があります。

ヘッダーを反復処理すると、ヘッダーtoString()が削除されます。

    Iterator it = headers.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry) it.next();
        result += pairs.getKey() + ": " + pairs.getValue() + "\n";
        it.remove();
    }

それが望ましい動作である場合は、このロジックに別の名前のメソッドを使用することをお勧めします。

toString()のメソッドをオーバーライドするためObject、呼び出されることを想定していない場所で呼び出され、ヘッダー マップが空になる可能性があります。

于 2013-06-28T16:30:34.403 に答える