簡體   English   中英

Spring Boot ConnectException 沒有被捕獲

[英]Spring Boot ConnectException not getting caught

我正在使用 RestTemplate 連接到另一個服務,並且我正在捕獲 ConnectException,但是 catch 塊從未捕獲它。 異常在 result = restTemplate.getForEntity(uri, String.class) 行中拋出,在控制台中我確實得到了這個:

java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method) ~[na:1.8.0_201]
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) ~[na:1.8.0_201]
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_201]
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_201]
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_201]
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_201]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_201]
    at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_201]
    at java.net.Socket.connect(Socket.java:538) ~[na:1.8.0_201]
    at sun.net.NetworkClient.doConnect(NetworkClient.java:180) ~[na:1.8.0_201]
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) ~[na:1.8.0_201]
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) ~[na:1.8.0_201]
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[na:1.8.0_201]
    at sun.net.www.http.HttpClient.New(HttpClient.java:339) ~[na:1.8.0_201]
    at sun.net.www.http.HttpClient.New(HttpClient.java:357) ~[na:1.8.0_201]
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220) ~[na:1.8.0_201]
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156) ~[na:1.8.0_201]
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050) ~[na:1.8.0_201]
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984) ~[na:1.8.0_201]
    at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:338) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at com.tdl.controller.ToDoNoteController.addUserToNote(ToDoNoteController.java:323) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_201]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_201]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.16.jar:9.0.16]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]

郵遞員的回應:

{
    "timestamp": "2019-04-24T15:48:25.395+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "I/O error on GET request for \"http://friend:5000/users/Soras2@gmail.com\": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect",
    "path": "/todos/1/users"
}

方法本身:

@PostMapping("/todos/{toDoNoteId}/users")
    public ResponseEntity<?> addUserToNote(@RequestBody User user,@PathVariable int toDoNoteId) throws JsonParseException, JsonMappingException, ConnectException, IOException{
        String email = user.getEmail();
        final String uri = "http://friend:5000/users/"+email;
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> result =null;
        int statusCode=0;
        ObjectMapper mapper = new ObjectMapper();
        //ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);

        //return null;

        try { // If user exists we will just add it to our ToDoNote

             result = restTemplate.getForEntity(uri, String.class); // exception thrown here

             ResponsePojo pojo = mapper.readValue(result.getBody(), ResponsePojo.class);
             User userToRespond = new User(pojo.getData().getEmail(),pojo.getData().getFirstName(),pojo.getData().getLastName());
             ToDoNote toDoNote = toDoNoteService.getToDoNoteById(toDoNoteId);
             if(toDoNote.checkIfUserExists(userToRespond)==true) {
                    return new ResponseEntity<String>("\"User already in this note\"",HttpStatus.CONFLICT);
             }
                else {
                    toDoNoteService.getToDoNoteById(toDoNoteId).addUser(userToRespond);
                    return new ResponseEntity<User>(userToRespond,HttpStatus.CREATED);
                }

            //System.out.println("result" + result);


        }
        catch(ConnectException ex2) {
            System.out.println(ex2.getCause());
            return new ResponseEntity<String>("\"Coudl not connect\"",HttpStatus.CONFLICT);
        }

        catch (HttpClientErrorException ex) {
            System.out.println("value"+ ex.getStatusCode().value());
            statusCode=ex.getStatusCode().value();     
        }


        try { // If user does not exist by the given email we can POST
            if(statusCode==404) {
                if(user.getEmail()==null || user.getFirstName()==null || user.getLastName()==null) {
                     return new ResponseEntity<String>("\"Required fields are missing( required fields are email,firstName,LastName)\"",HttpStatus.BAD_REQUEST);
                }
                final String uriPost = "http://friend:5000/users";
                result= restTemplate.postForEntity(uriPost, user, String.class);
                System.out.println("result" + result);

                ResponsePojo pojo = mapper.readValue(result.getBody(), ResponsePojo.class);
                User userToRespond = new User(pojo.getData().getEmail(),pojo.getData().getFirstName(),pojo.getData().getLastName());
                toDoNoteService.getToDoNoteById(toDoNoteId).addUser(userToRespond);
                return new ResponseEntity<User>(userToRespond,HttpStatus.CREATED);
            }
        }
            catch (HttpClientErrorException ex) {
                System.out.println("value"+ ex.getStatusCode().value());
                return ResponseEntity.status(ex.getRawStatusCode()).headers(ex.getResponseHeaders())
                        .body(ex.getResponseBodyAsString());
            }
    // istryniau daug tu throws not sure if thats that good

        System.out.println("Rip");
        return null;

    }

唯一有效的方法是捕獲 Exception 或 RestClientException,但是我希望捕獲 ConnectException 本身。 有誰知道我錯過了什么?

這是關鍵部分:

嵌套異常是 java.net.ConnectException

RestTemplate 的getForEntity拋出一個包含 ConnectException 的 RestClientException。 這不像引用父類型——RestClientException 不擴展 ConnectException,所以你不能只是嘗試捕捉包裝的類型。

我不確定您為什么反對捕獲 Exception 或 RestClientException。 如果我只想有特定的邏輯來處理 ConnectException,我會捕獲 RestClientException,然后檢查內部異常的類型(如果它不是 ConnectException,則重新拋出。)

所以像這樣:

try {
    response = restTemplate.getForEntity( ... );
    // omitted for brevity
} catch (RestClientException e) {
  if (e.getCause() instanceof ConnectException) {
    // handle connect exception 
    return ResponseEntity.status(HttpStatus.CONFLICT).body("Could not connect");
  }
  throw e; // rethrow if not a ConnectException
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM