【问题标题】:Servlet parameters and doPutServlet 参数和 doPut
【发布时间】:2021-08-11 16:13:56
【问题描述】:

尝试使用 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 请求可以正常工作。我错过了什么吗?

【问题讨论】:

    标签: java rest servlets


    【解决方案1】:

    doPut() 不起作用是什么意思?据我所知,它不像doGet()doPost() 那样工作,你有请求参数和东西。

    PUT 可用于在服务器上放置一些东西。具体来说,PUT 操作允许客户端将文件放在服务器上,类似于通过 FTP 发送文件。看看这个例子,我在 JGuru 上找到的。

    ->GET /file.dat HTTP/1.1
    
    <-HTTP/1.1 404 Not Found
    
    ->PUT /file.dat HTTP/1.1
    Content-Length: 6
    Content-Type: text/plain
    
    Hello!
    
    <-HTTP/1.1 200 OK
    
    ->GET /file.dat HTTP/1.1
    
    <-HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: text/plain
    
    Hello!
    

    【讨论】:

    • ??????????
    【解决方案2】:

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

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

    BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream());
    
    String data = br.readLine();
    

    【讨论】:

    • 我遇到了同样的问题:我正在尝试实现一个 restfull 服务,PUT 是为了替换资源。 Jetty 在请求参数映射中提供所有数据,但是 tomcat 没有..
    • 根据 Java Web Services: Up and Running,“doPost 和 doPut 差异很大,因为 servlet 容器运行时不会生成可用的参数映射。(Tomcat 和 Jetty 都是这种情况)”
    【解决方案3】:

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

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

    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 库来解析参数。 有关包含doGet()doPost()doPut()doDelete() 方法的完整示例,您可以阅读我的Using jsGrid tutorial

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-02
      • 1970-01-01
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      相关资源
      最近更新 更多