美文网首页
Spring结合Ajax实现delete、put的restful

Spring结合Ajax实现delete、put的restful

作者: henry技术探索记录员 | 来源:发表于2019-03-19 16:56 被阅读0次

由于项目采用restful的接口风格,自然会用到delete和put请求,但实现delete、put请求还是踩到了坑。
前端采用Jquery的Ajax接口:

$.ajax({
    type: "delete",
    url: encodeURI('xxx/yyy'),
    data: {var1: xxx, var2: xxx, ...}
    async: true,
    processData: false,
    success: function (data) {
        callback(data);
    },
    error: function (e) {
        callback({status: {code: 'error', message: e}});
    }
});

后端Spring的controller的代码:

@RequestMapping(value = "xxx/yyy", method = RequestMethod.DELETE)
public JSONObject deleteEntity(@RequestParam("var1")Long var1,
                             @RequestParam("var2")String var2
                             @RequestParam("var3")Float var3) {
                             ...
}

请求后报400错误。
于是从前端代码排除,将procesData选项设置为truefalse都没效果;
再将contentType设为text/htmlapplication/json,还是没效果。

网上的一些资料说将前端的ajax请求的type设置为postdata加上_method: 'delete'参数:

$.ajax({
    type: "post",
    url: encodeURI('xxx/yyy'),
    data: {var1: xxx, var2: xxx, ..., _method: 'delete'}
    success: function (data) {
        callback(data);
    },
    error: function (e) {
        callback({status: {code: 'error', message: e}});
    }
});

Spring后端代码RequestMapping加上produces = "text/html"

@RequestMapping(value = "xxx/yyy", produces = "text/html", method = RequestMethod.DELETE)
public JSONObject deleteEntity(@RequestParam("var1")Long var1,
                             @RequestParam("var2")String var2
                             @RequestParam("var3")Float var3) {
                             ...
}

果然,请求接收成功!
不过请求最终还是没有成功返回,抛出500服务器异常:

2017-08-07 16:57:12 WARN  ExceptionHandlerExceptionResolver 391 doResolveHandlerMethodException - Failed to invoke @ExceptionHandler method: public com.alibaba.fastjson.JSONObject com.polyzg.polyzgoaserver.controller.ExceptionController.unkownException(java.lang.Exception) org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:259) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:174) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:113) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:384) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:59) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:136) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:74) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1222) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1034) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:984) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:392) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:311) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:395) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:254) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_45]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45]

异常为HttpMediaTypeNotAcceptableException,因此可断定是请求返回的数据responseBodyMIME类型不相符。
再仔细看Controller的deleteEntity方法:

@RequestMapping(value = "xxx/yyy", produces = "text/html", method = RequestMethod.DELETE)
public JSONObject deleteEntity(@RequestParam("var1")Long var1,
                             @RequestParam("var2")String var2
                             @RequestParam("var3")Float var3) {
                             ...
}

RequestMapping的参数produces = "text/html", 说明要返回的是text/html格式的页面,而函数实际返回的是JSONObject
produces = "text/html"改为produces = "application/json",delete请求成功并正确返回json数据!

另外测试了必须将ajax请求的processData参数设置为true才行,若设置为false则抛出406异常。

因此,最终最佳的处理方法是:

前端代码:
$.ajax({
    type: "post",
    url: encodeURI('xxx/yyy'),
    data: {var1: xxx, var2: xxx, ..., _method: 'delete'},
    async: true,
    processData: true,
    success: function (data) {
        callback(data);
    },
    error: function (e) {
        callback({status: {code: 'error', message: e}});
    }
});
后端代码:
@RequestMapping(value = "xxx/yyy", produces = "application/json", method = RequestMethod.DELETE)
public JSONObject deleteEntity(@RequestParam("var1")Long var1,
                             @RequestParam("var2")String var2
                             @RequestParam("var3")Float var3) {
                             ...
}

对于PUT请求,类似的实现方法,就不再赘述。

相关文章

网友评论

      本文标题:Spring结合Ajax实现delete、put的restful

      本文链接:https://www.haomeiwen.com/subject/jvmvpqtx.html