繁体   English   中英

如何解析 Java 中的 Http POST 响应正文

[英]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

现在程序无法知道只有两个参数, candyfruit 现在看来有三个: candyMs (没有对应的值)和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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM