【问题标题】:How to parse Http POST response body in Java如何在 Java 中解析 Http POST 响应正文
【发布时间】:2021-04-18 17:08:35
【问题描述】:

收到标准 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 库以安全的方式解析表单条目?

【问题讨论】:

    标签: java forms parsing post


    【解决方案1】:

    首先,URLDecoder.decode is a static method。调用时不要创建 URLDecoder 的实例。 (其实that constructor is now deprecated.

    其次,不要捕获 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 中没有用于解析查询参数的方法(尽管很多人都要求使用它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 2016-06-20
      相关资源
      最近更新 更多