我正在使用Java Jersey 2.17构建RESTful Web服务。客户。我正在使用ExtJS 5开发。
我在服务上的课程
Main.java
public class Main { public static final String BASE_URI = "http://localhost:8080/app/rest/"; public static HttpServer startServer() { final ResourceConfig rc = new ResourceConfig(); rc.packages(true, "app"); rc.register(ResponseCorsFilter.class); return GrizzlyHttpServerFactory.createHttpServer(URI.create(Main.BASE_URI), rc); } public static void main(final String[] args) throws IOException { final HttpServer server = Main.startServer(); System.out.println(String.format("Jersey app started with WADL available at " + "%sapplication.wadl\nHit enter to stop it...", Main.BASE_URI)); System.in.read(); server.stop(); } }
UserRi.java
@Path("/user") public class UsersRi { @DELETE @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) public String deleteUser(@PathParam("id") final String id) { final String res = "{\"success\":true,\"msg\":\"User " + id + " successfully deleted.\"}"; return res; } }
ResponseCorsFilter.java
public class ResponseCorsFilter implements ContainerResponseFilter { @Override public void filter(final ContainerRequestContext req, final ContainerResponseContext contResp) { contResp.getHeaders().add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); contResp.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); contResp.getHeaders().add("Access-Control-Allow-Origin", "*"); final String reqHead = req.getHeaderString("Access-Control-Request-Headers"); if ((null != reqHead) && StringUtils.isNotBlank(reqHead)) { contResp.getHeaders().add("Access-Control-Request-Headers", reqHead); } } }
目前,我一直坚持删除内容。在客户端上,我从表单面板中获取记录并调用擦除功能。请求/响应看起来像这样:
General: Remote Address:127.0.0.1:8080 Request URL:http://localhost:8080/app/rest/user/user4 Request Method:DELETE Status Code:400 Bad Request Response Headers Connection:close Content-Length:0 Date:Tue, 14 Apr 2015 19:26:05 GMT Request Headers Accept:*/* Accept-Encoding:gzip, deflate, sdch Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4 Connection:keep-alive Content-Length:14 Content-Type:application/json Host:localhost:8080 Origin:http://localhost Referer:http://localhost/app/ User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36 X-Requested-With:XMLHttpRequest Request Payload {"id":"user4"}
在控制台上,我看到了 XMLHttpRequest cannot load http://localhost:8080/app/rest/user/user4. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. The response had HTTP status code 400.
XMLHttpRequest cannot load http://localhost:8080/app/rest/user/user4. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. The response had HTTP status code 400.
也可以通过以下jQuery.ajax()调用来重现它: $.ajax({method:'DELETE',url:"http://localhost:8080/app/rest/user/user4",data:{"id":"user4"}})
$.ajax({method:'DELETE',url:"http://localhost:8080/app/rest/user/user4",data:{"id":"user4"}})
发送不带表单数据或有效负载的请求正在运行。
还有另一种方法可以解决此问题而不覆盖ExtJS框架中的内容吗?
问候
DELETE,以及GET请求不应具有有效负载(实体)。我不知道是否在任何地方指定此名称,但是您可以在此处查看讨论。
DELETE
GET
这就是原因400 Bad Request(对于GET也会发生)。摆脱它,它将起作用。但是无论如何,甚至不需要发送该正文,就像您一样,只有信息是id,该信息已经包含在URL路径中。
400 Bad Request
id
如果仅是示例,并且您需要与请求一起发送其他一些任意信息,则使用查询参数,例如
/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) {}
使用jQuery,您可以做到
var params = { some:"valeu1", other:"value2", data:"value3" } var encoded = $.param(params); var url = baseUrl + "?" + encoded; $.ajax({ url: url, ... })
因此,经过一些调查,这似乎是一个灰熊问题。我已经对Jetty进行了测试,并且效果很好。
看到类似的问题
因此,如@alexey在下面的评论中所述
没错,默认情况下,Grizzly不允许HTTP方法的有效负载,而HTTP规范对此并未明确说明。像HTTP GET,DELETE和HEAD。但是您可以通过调用以下方式打开支持:httpServer.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true);请不要在开始之前调用该方法HttpServer
httpServer.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true);
HttpServer
所以解决办法是做类似
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(); }
经过测试,可以正常工作。