Servlet parameters and doPut

2020-02-05 18:51发布

问题:

Trying to get parameters from a PUT request using HttpServlet#doPut:

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

Using curl to send the request:

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

works fine with using doGet and GET curl request. Am I missing something?

回答1:

Based on comments and further research I realized that the Servlet cannot assume anything about the data being put onto the server and therefore, will not parse name/value pairs.

The following solution seems to be the proper way to handle any data passed via PUT, and can be parsed as XML, Name/Value, or whatever.

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

String data = br.readLine();


回答2:

Unlike in doGet() and doPost() methods, we are not able to get the request parameters using the getParameter() method in doPut() and doDelete() methods. We need to retrieve them manually from the input stream.

The following method retrieves request parameters and returns them in a map:

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;
}

The example uses Google's Guava library to parse the parameters. For a complete example containing doGet(), doPost(), doPut() and doDelete() methods, you can read my Using jsGrid tutorial.



回答3:

What do you mean by doPut() is not working? As far as I know, it doesn't work like doGet() or doPost(), where you have request parameters and stuff.

PUT can be used to put something on the server. In particular, the PUT operation allows a client to place a file on the server and is similar to sending a file by FTP. Check out this example, I found on 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!