2017-07-25 14 views
8

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

+0

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? –

+0

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? –

+0

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) –

Trả lời

1

Bởi vì nó gói một IOException, không nhìn vào mã phản hồi thực tế.

Nguyên nhân gốc có vẻ là do BufferingClientHttpResponseWrapper đang cố gắng đọc một cơ thể mà không kiểm tra xem có đầu tiên không.

+0

là có cách nào để có được httpStatus và responseBody? – gstackoverflow

+0

@gstackoverflow ý của bạn là gì? Có một lỗi trong 'BufferingClientHttpResponseWrapper', một lớp mà OP đã viết. – OrangeDog

+1

@gstackoverflow bạn nên đặt tiền thưởng vào câu hỏi thực tế của mình. Trong khi tôi vui vẻ lấy 100 của bạn, câu hỏi này là hoàn toàn không liên quan. – OrangeDog

Các vấn đề liên quan