POST request becomes GET

2020-07-17 06:21发布

I am developing an Android and a server application in Java. The server application runs on Jetty. The Android application is emulated on the same computer.

The Android application sends a POST request to the server, but the handler of the server interpret it as a GET.

When I use Send HTTP Tool to simulate POST request, it works perfectly (I mean the type of the method is POST).

This is the code-fragment of the Android application:

HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(),
        10000); // Timeout Limit
HttpResponse response;

// Create message
JSONObject json = new JSONObject();
json.put("request_type", "info");
json.put("user_name", mEmail);

// Send message and get response
StringEntity se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
HttpPost post = new HttpPost("http://10.0.2.2:8080/app");
post.setEntity(se);
post.setHeader("Accept", "application/json");
post.setHeader("Content-Type", "application/json; charset=UTF-8");
response = client.execute(post);

And this is the code of the handler:

public void handle(String target, Request baseRequest, 
    HttpServletRequest request, HttpServletResponse response) {
    System.out.println(request.getMethod());
}

I don't know what could be a problem, as I think if I use HttpPost, the method type should be POST.

1条回答
Summer. ? 凉城
2楼-- · 2020-07-17 06:31

If you could, could you please post your complete handler, or the handler initialisation. But I am going to take a guess on the answer.

I have a feeling that your POST request is actually getting redirected via a 302, so the handler is correctly receiving it as a GET request.

By default a Jetty ContextHandler with a context of "/app" will actually redirect any request to "/app" to "/app/", have a look at setAllowNullPathInfo.

So you have 2 possible solutions, call setAllowNullPathInfo(true) on your ContextHandler, or change your post url on the client to HttpPost post = new HttpPost("http://10.0.2.2:8080/app/");

It might help you to enable RequestLogs on jetty, see Jetty/Tutorial/RequestLog

Using the following server you can see the difference between a request to /app and a request to /app/ via the request log.

public class RequestLogPost {

  public static class PostHandler extends ContextHandler {
    public PostHandler() {
      setContextPath("/app");
      // setAllowNullPathInfo(true); // enable to see difference in request handling
    }

    @Override
    public void doHandle(String target, Request baseRequest, HttpServletRequest request,
        HttpServletResponse response) throws IOException, ServletException {
      System.out.println(request.getMethod());
      response.setStatus(HttpStatus.OK_200);
      baseRequest.setHandled(true);
    }
  }

  public static void main(String[] args) throws Exception {
    Server server = new Server(5555);

    HandlerCollection handlers = new HandlerCollection();
    handlers.addHandler(new PostHandler());
    handlers.addHandler(new DefaultHandler());
    handlers.addHandler(createRequestLogHandler());

    server.setHandler(handlers);

    server.start();
    server.join();
  }

  private static RequestLogHandler createRequestLogHandler() {
    final int RETAIN_FOREVER = 0; // see RolloverFileOutputStream, 0 == forever.
    RequestLogHandler logHandler = new RequestLogHandler();

    NCSARequestLog ncsaRequestLog = new AsyncNCSARequestLog("requests.log");
    ncsaRequestLog.setAppend(true);
    ncsaRequestLog.setExtended(true);
    ncsaRequestLog.setLogTimeZone("GMT");
    ncsaRequestLog.setRetainDays(RETAIN_FOREVER);
    logHandler.setRequestLog(ncsaRequestLog);
    return logHandler;
  }
}

From the request logs, Post request to "/app", resulting in a 302

[30/Jul/2013:12:28:09 +0000] "POST /app HTTP/1.1" 302 0

[30/Jul/2013:12:28:09 +0000] "GET /app/ HTTP/1.1" 200 0

Direct request to "/app/":

[30/Jul/2013:12:28:16 +0000] "POST /app/ HTTP/1.1" 200 0

查看更多
登录 后发表回答