簡體   English   中英

在put()之后,哈希表保持為空

[英]Hashtable remains empty after put()

我在此類中使用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之后,哈希表為空。 消耗數據:

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

}

toString()修改對象似乎是個壞主意。 toString()的目的是返回對象的String表示形式。 后續對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的方法,所以有可能在您不希望調用它的地方調用了它,並清空了標題映射。

調試器在Hashtable上調用toString ,因此您看到的是顯示的值。 但是調用此方法也會刪除這些值,因此在調試器中查看它實際上會清空該表。 這是一個壞主意,您的toString方法不應修改該對象。

而且您的HttpBuilder是線程安全的,因為您使用的是Hashtable 幸運的是,至少您沒有從多個線程中調用它,至少沒有在已發布的代碼中調用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM