【问题标题】:Spring Cloud 1.0.2 and SR3 RestTemplate ignoring my ResponseErrorHandlerSpring Cloud 1.0.2 和 SR3 RestTemplate 忽略了我的 ResponseErrorHandler
【发布时间】:2016-02-23 15:07:29
【问题描述】:

使用 Spring Cloud,我无法使用最新版本在我的 RestTemplate 上使用自定义 ResponseErrorHandler 消除抛出的异常。一年前,我们实现了类似于How to Ignore HttpStatus Exceptions 的东西。这一直有效,直到我们移植到 spring boot/cloud 1.0.2 及更高版本。使用 Spring Cloud 1.0.2 或 SR3 时,在发生超时或连接问题时在这些处理程序中设置断点不会在调试模式下触发。

@Configuration
class MyConfig {
    :
    @Bean
    public RestTemplate restTemplate() {
      RestTemplate toRet = new RestTemplate(httpRequest());
      toRet.setErrorHandler(new ExceptionLessErrorHandler());
      return toRet;
    }
} 

ExceptionLessErrorHandler.java

public class ExceptionLessErrorHandler implements ResponseErrorHandler {
      @Override
      public boolean hasError(ClientHttpResponse response) {
        return false;
      }
      @Override
      public void handleError(ClientHttpResponse response)  throws IOException {
        logger.error("handleError called with {}", response);
        // do nothing!
      }
}

最后当我们调用时,使用相同的 restTemplate(我验证 ErrorHandler 设置为 ExceptionLessErrorHandler)

@Autowired
private RestTemplate restTemplate;
:
class GetRemoteJsonResponse implements Callable<List<JsonNode>> {
: 
  @Override
  public List<JsonNode> call() {
    :
    ResponseEntity<String> remoteUsers = restTemplate.getForEntity(URL.toString(), String.class, params);
  }
}

java.net.SocketTimeoutException: connect timed out 引发了异常。这不是我们移植之前的行为(我们使用的是 Spring 3.2.4)。

更新。具体发布spring-cloud-starter-parent

<parent>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-parent</artifactId>
    <version>Angel.SR3</version>
    <!--<version>1.0.2</version>-->
    <relativePath />
</parent>

除了这两个之外,我还没有尝试过其他 spring-cloud-starter-parent 版本。

【问题讨论】:

  • spring cloud 1.0.2 没有意义,SR3 才有意义,因为只有 Angel 有和 SR3。你是说 spring-cloud-netflix 1.0.2 吗?
  • @spencergibb - 我更新得更具体了。

标签: java spring spring-boot spring-cloud


【解决方案1】:

如果异常是连接问题的结果,则不会调用 ResponseErrorHandler,因为它仅用于响应问题。我知道,阻止连接问题引发异常的唯一方法是通过 HttpConnectionFactory 添加某种 localhost 代理。

【讨论】:

  • 是的,就是这样。我看到 RestTemplate.doExecute 仅在 request.execute() 方法之后使用 ResponseErrorHandler 。该方法以 ClientHttpRequest 实现结束,如果 connect() 失败,该实现将引发异常。该异常直接跳过 RestTemplate 的 handleResponse() 方法,并在该方法中重新抛出。因此,这是一种 spring-web 行为,而不是 Spring Cloud。这不太可能会改变。
【解决方案2】:

这是我必须为天使发布火车做的事情:

@Bean
@Qualifier("custom")
public RestTemplate restTemplate(RestTemplateCustomizer customizer) {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setErrorHandler(new ExceptionLessErrorHandler());
    customizer.customize(restTemplate); //this brings in ribbon.
    return restTemplate;
}

@Autowired
@Qualifier("custom")
RestTemplate rest;

Angel.X 创建了一个RestTemplate,而您得到的是自动创建的,而不是您创建的。

我还创建了an issue 以使其更加用户友好并记录如何执行此操作。

【讨论】:

  • 所以我现在还有几个问题。 RestTemplateCustomizer 不是用于自定义@LoadBalanced RestTemplate 吗?由于我没有用@LoadBalanced 注释RestTemplate bean 函数,我应该传入定制器吗?另外,由于RestTemplateCustomizer 是一个接口,我从哪里得到它?我在该功能上尝试了@Autowired 无济于事。
  • 是的,但您必须复制 s-c-netflix 定制器。 Brixton 中有一个修复程序允许多个定制器。
猜你喜欢
  • 2018-09-08
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 2013-08-07
  • 1970-01-01
  • 2015-10-23
  • 2018-04-23
  • 2020-02-06
相关资源
最近更新 更多