DELETE Request with Payload or Form Data causes Bad Request

后端 未结 2 1852
天命终不由人
天命终不由人 2021-01-22 05:14

I am building a RESTful Web Service with Java Jersey 2.17. The Client for it. I am developing with ExtJS 5.

My classes on the service

Main.java

          


        
相关标签:
2条回答
  • 2021-01-22 06:04

    By using @Path on method level, you are overriding the defined @Path at class level.

    If you are using Apache Tomcat, use their CORS lib: Tomcat CORS filter. This way it is cleaner and covers all the exceptions as well.

    0 讨论(0)
  • 2021-01-22 06:15

    DELETE, as well as GET requests should not have a payload (entity body). I don't know if this is specified anywhere, but you can see discussion here.

    That's what's causing the 400 Bad Request(will occur for GET also). Get rid of it, and it will work. But anyway there is not even a need to send that body, as you are, only information is the id, which is already included in the in the URL path.

    If that's just an example, and you need to send some other arbitrary information along with the request, then use query params, e.g.

     /app/rest/user/user4?some=value1&other=value2&data=value3
    
     public String deleteUser(@PathParam("id") final String id,
                              @QueryParam("some") String some,
                              @QueryParam("other") String other,
                              @QueryParam("data") String data) {}
    

    With jQuery, you could do

    var params = {
        some:"valeu1",
        other:"value2",
        data:"value3"
    }
    
    var encoded = $.param(params);
    var url = baseUrl + "?" + encoded;
    $.ajax({
        url: url,
        ...
    })
    

    UPDATE

    So after some investigation, this seems to be a Grizzly problem. I've tested with Jetty, and it works fine.

    See similar issue

    • Here - last comment says it's fixed, but I can't produce a working example
    • Here

    UPDATE 2

    So as @alexey stated in a comment below

    You're right, Grizzly by default doesn't allow payload for HTTP methods, for which HTTP spec doesn't explicitly state that. Like HTTP GET, DELETE, HEAD. But you can switch the support on by calling: httpServer.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true)‌​; Please not the method should be called before starting HttpServer

    So the fix would be to do something like

    public static HttpServer createServer() {
        final ResourceConfig rc = new ResourceConfig();
        rc.packages(true, "app");
        rc.register(ResponseCorsFilter.class);
        
        HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
                                   URI.create(BASE_URI), rc, false);
        server.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true);
        return server;
    }
    
    public static void main(String[] args) throws IOException {
        final HttpServer server = createServer();
        server.start();
        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.stop();
    }
    

    Tested and it works as expected.

    0 讨论(0)
提交回复
热议问题