Sử dụng Spring 4.3.1 trên Apache Tomcat 8.5, Chúng tôi đã triển khai một máy chủ REST xử lý các yêu cầu PUT, POST & PUT. Yêu cầu POST được xử lý theo hình thức:Ném ResourceAccessException và HttpClientErrorException cho máy khách RestTemplate trong Spring
@POST
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Transactional
public Response postMethod(final MyDomain object) {
domainHandler.createDomain(object);
return Response.status(201).entity(object).build();
}
Trong xử lý yêu cầu POST ở phía máy chủ, các WebApplicationException được ném, mà được xử lý bởi:
@Provider
public class WebExceptionMapper implements ExceptionMapper<WebApplicationException> {
@Override
public Response toResponse(WebApplicationException exception) {
int httpStatus = exception.getResponse().getStatus();
ErrorMessage em = new WebErrorMessage(exception.getMessage());
return Response.status(httpStatus).entity(em).build();
}
}
Về phía khách hàng:
response = rest.exchange(requestURL, method, requestEntity, MyDomain.class);
ResourceAccessException được ném:
2017-07-25 15:46:41,489 ERROR [com.my.code.web.presentation.ManagementController:63] (http-nio-8080-exec-7#34): Internal exception occured with cause:
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8080/": Server returned HTTP response code: 500 for URL: http://localhost:8080/; nested exception is java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:8080/
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:633) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:498) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at com.my.code.web.integration.client.rest.FeedbackRestClient.callForApiCreateFeedback(FeedbackRestClient.java:218) ~[classes/:?]
at com.my.code.web.integration.client.rest.FeedbackRestClient.pushFeedbackData(FeedbackRestClient.java:70) ~[classes/:?]
at com.my.code.web.presentation.FeedbackController.feedback(FeedbackController.java:91) ~[classes/:?]
at sun.reflect.GeneratedMethodAccessor72.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [servlet-api.jar:?]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [servlet-api.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [catalina.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.16]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.16]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.16]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [catalina.jar:8.5.16]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:8.5.16]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [catalina.jar:8.5.16]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [catalina.jar:8.5.16]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [catalina.jar:8.5.16]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624) [catalina.jar:8.5.16]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [catalina.jar:8.5.16]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [catalina.jar:8.5.16]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-coyote.jar:8.5.16]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:8.5.16]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-coyote.jar:8.5.16]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-coyote.jar:8.5.16]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:8.5.16]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.5.16]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: http://localhost:8080/
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1876) ~[?:1.8.0_131]
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474) ~[?:1.8.0_131]
at org.springframework.http.client.SimpleClientHttpResponse.getBody(SimpleClientHttpResponse.java:85) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at com.my.code.web.integration.client.rest.BufferingClientHttpResponseWrapper.getBody(BufferingClientHttpResponseWrapper.java:46) ~[classes/:?]
at com.my.code.web.integration.client.rest.LoggingRequestInterceptor.traceResponse(LoggingRequestInterceptor.java:66) ~[classes/:?]
at com.my.code.web.integration.client.rest.LoggingRequestInterceptor.intercept(LoggingRequestInterceptor.java:34) ~[classes/:?]
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:85) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:69) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:619) ~[spring-web-4.3.1.RELEASE.jar:4.3.1.RELEASE]
... 47 more
Câu hỏi:
Tại sao ngoại trừ org.springframework.web.client.ResourceAccessException
được ném, nhưng không org.springframework.web.client.HttpClientErrorException
, những gì đang xảy ra để xử lý các yêu cầu GET khi WebApplicationException
xảy ra?
Các ResourceAccessException
ngoại lệ không có phương pháp cho phép tôi để đọc các trạng thái HTTP, ví dụ như getRawStatusCode()
, getResponseHeaders()
vv
Tất cả dấu vết ngoại lệ mà bạn đã đăng là phía máy khách. API đang ném 500 và phần còn lại của ánh xạ ngoại lệ xảy ra trong ngữ cảnh của ứng dụng khách. Bạn có thể vui lòng thử thêm một số đăng nhập bổ sung ở phía máy chủ - WebExceptionMapper để xác thực nếu khối mã đang được thực thi không? –
Những điều thực sự kỳ lạ với stacktrace của bạn: "Ngoại lệ nội bộ xảy ra với nguyên nhân: [...] Máy chủ trả lại mã phản hồi HTTP: 500 cho URL" trong mã bị chặn nhưng "IOException: Máy chủ trả lại mã phản hồi HTTP: 400 cho URL [.. .] "trong nguyên nhân. Nó thực sự là stacktrace của bạn hoặc bạn đã làm một bản sao sai/dán? –
Url ngoại lệ của bạn là "http: // localhost: 8080 /" và trong phương thức chấp nhận yêu cầu @POST của bạn chưa xác định đây là yêu cầu chấp nhận mặc định như @RequestMapping (value = "/", method = RequestMethod.POST) –