Servlet 参数和 doPut

2022-09-02 20:47:26

尝试使用 HttpServlet#doPut 从 PUT 请求中获取参数:

public void doPut(HttpServletRequest request, HttpServletResponse response) {
    String name = request.getParameter("name");
    // name is null
}

使用 curl 发送请求:

curl  -X PUT \
      --data "name=batman" \
      --header "Content-Type: text/plain" http://localhost:8080/sample.html

使用 doGet 和 GET curl 请求工作正常。我错过了什么吗?


答案 1

根据评论和进一步的研究,我意识到Servlet不能假设任何关于被放到服务器上的数据,因此不会解析名称/值对。

以下解决方案似乎是处理通过 PUT 传递的任何数据的正确方法,并且可以解析为 XML、名称/值或其他任何内容。

BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream());

String data = br.readLine();

答案 2

与 in 和 方法不同,我们无法使用 in 和 方法获取请求参数。我们需要从输入流中手动检索它们。doGet()doPost()getParameter()doPut()doDelete()

以下方法检索请求参数并在映射中返回这些参数:

public static Map<String, String> getParameterMap(HttpServletRequest request) {

    BufferedReader br = null;
    Map<String, String> dataMap = null;

    try {

        InputStreamReader reader = new InputStreamReader(
                request.getInputStream());
        br = new BufferedReader(reader);

        String data = br.readLine();

        dataMap = Splitter.on('&')
                .trimResults()
                .withKeyValueSeparator(
                        Splitter.on('=')
                        .limit(2)
                        .trimResults())
                .split(data);

        return dataMap;
    } catch (IOException ex) {
        Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException ex) {
                Logger.getLogger(Utils.class.getName()).log(Level.WARNING, null, ex);
            }
        }
    }

    return dataMap;
}

该示例使用 Google 的 Guava 库来解析参数。有关包含 、 和 方法的完整示例,您可以阅读我的使用 jsGrid 教程doGet()doPost()doPut()doDelete()