[英]How to parse Http POST response body in Java
為標准 JDK lib 接收 html 表單帖子,並使用 HttpExchange 獲取並傳遞給
private String getBodyString(HttpExchange he){
String ret=null;
InputStream is = he.getRequestBody();
URLDecoder dc = new URLDecoder();
try {
ret = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)).readLine();
ret = dc.decode(ret, StandardCharsets.UTF_8.name());
}catch (NullPointerException ex){
Logger.getLogger(RequestBodyParser.class.getName()).log(Level.SEVERE, null, ex);
}catch (IOException ex) {
Logger.getLogger(RequestBodyParser.class.getName()).log(Level.SEVERE, null, ex);
}
return ret;
}
返回:
mytxt1=huhu&mytxt2=haha&btnOk=1
其中 mytxt1 和 mytxt2 是輸入。 現在我想從中解析鍵(名稱)和值(文本)。
這是一個很好的例子。 我可以很容易地用“&”進行一些字符串拆分,並用“=”划分鍵和值。 但也有不好的地方:
mytxt1=huhu & haha &mytxt2=haha&btnOk=1
...和丑陋的:
mytxt1=Lorem &mytxt2=Ugly Injection&mytxt2=haha&btnOk=1
而且我還沒有開始談論“選擇多個”。 是否有任何最佳實踐可以使用包含的 JDK 庫以安全的方式解析表單條目?
首先, URLDecoder.decode 是一個 static 方法。 調用時不要創建 URLDecoder 的實例。 (事實上, 該構造函數現在已被棄用。 )
其次,不要捕獲 NullPointerException。 NullPointerException 表示程序員犯了一個錯誤。 如果發生 NullPointerException,程序員需要修復錯誤,而不是隱藏它。
第三,您不應將整個查詢傳遞給單個 URLDecoder.decode 調用。 當您這樣做時,您將失去區分實際表示查詢參數名稱和值的&
和=
字符以及實際名稱或值中存在的&
和=
字符的能力。
例如,如果我從這個查詢開始:
candy=M%26Ms&fruit=pineapple
然后我將整個查詢傳遞給 URLDecoder.decode,我最終得到這個:
candy=M&Ms&fruit=pineapple
現在程序無法知道只有兩個參數, candy
和fruit
。 現在看來有三個: candy
、 Ms
(沒有對應的值)和fruit
。
解決這個問題的方法是首先拆分參數,然后拆分鍵/值對,然后解碼每個鍵和值。
private Map<String, List<String>> getBodyString(HttpExchange he) {
Map<String, List<String>> parameters = new LinkedHashMap<>();
String query;
try (InputStream body = he.getRequestBody()) {
query = new String(body.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
String[] keyValuePairs = query.split("&");
for (String keyValuePair : keyValuePairs) {
String[] keyAndValue = keyValuePair.split("=", 2);
String key = keyAndValue[0];
String value = keyAndValue.length > 1 ? keyAndValue[1] : "";
key = URLDecoder.decode(key, StandardCharsets.UTF_8);
value = URLDecoder.decode(value, StandardCharsets.UTF_8);
parameters.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
}
return parameters;
}
目前 Java SE 中沒有用於解析查詢參數的方法(盡管許多人都要求它)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.