SpringBoot - 网络请求模版类RestTemplate使用详解7(异常处理、请求失败处理)

作者: hangge 发布时间: 2019-11-26 浏览: 3377 次 编辑

当我们使用 RestTemplate 发送请求时, 如果接口返回的不是 200 状态(而是 4xx5xx 这样的异常状态),则会抛出异常报错。

原文:SpringBoot - 网络请求模版类RestTemplate使用详解7(异常处理、请求失败处理)

但在实际接口对接中,我们可能希望获取接口返回的异常信息并返回(比如返回到前端)。这个可以通过自定义 RestTemplate 异常的处理来实现,下面通过样例进行演示。

十、请求异常处理

1,简单的样例代码

(1)首先我们需要创建一个自己的异常处理控制器(ExceptionHandler 类),该类实现 ResponseErrorHandler 接口。

@Configuration
public class RestTemplateConfig {
 
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory){
        RestTemplate restTemplate = new RestTemplate(factory);
        //Response status code 4XX or 5XX to the client.
        restTemplate.setErrorHandler(new RestThrowErrorHandler());
        return restTemplate;
    }
 
    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(15000); // 连接超时
        factory.setReadTimeout(5000); // 数据读取超时时间
        return factory;
    }
}

(3)最后是一个简单的请求样例。经过上面设置后,无论请求成功或者失败都会返回(不会抛异常),所以我们需要通过状态码来判断请求是否成功。

@RestController
public class HelloController {
 
    @Autowired
    private RestTemplate restTemplate;
 
    @GetMapping("/test")
    public String test() {
        String url = "http://localhost:8080/xxxxxx";
        ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class);
        // 判断请求是否发生异常
        if(!responseEntity.getStatusCode().is2xxSuccessful()){
            // 返回异常信息
            return "请求失败,异常信息:" + responseEntity.getBody();
        }
        // 没有异常的话则返回正常的响应结果
        return responseEntity.getBody();
    }
}

(4)由于代码中我们请求了一个不存在的接口,并且在请求失败时将错误信息返回到前端,因此前端会显示如下内容:

原文:SpringBoot - 网络请求模版类RestTemplate使用详解7(异常处理、请求失败处理)

2,代码改进

(1)通常来说我们不会直接把业务代码写在 Controller 里,而是通过 Service 实现。首先我们创建一个 Service,里面调用 RestTemplate 进行网络请求,当请求异常时直接抛出异常。

@Service
public class UserService {
 
    @Autowired
    private RestTemplate restTemplate;
 
    public String getInfo() {
        String url = "http://localhost:8080/xxxxxx";
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        // 判断请求是否发生异常
        if(!responseEntity.getStatusCode().is2xxSuccessful()){
            // 抛出异常
            throw new RestClientException(responseEntity.getBody());
        }
        // 没有异常的话则返回正常的响应结果
        return responseEntity.getBody();
    }
}

(2)Controller 这边很简单,就是调用 Service 发起请求,然后返回结果。

@RestController
public class HelloController {
 
    @Autowired
    private UserService userService;
 
    @GetMapping("/test")
    public String test() {
        return userService.getInfo();
    }
}

(3)由于前面 Service 中我们将异常抛出了,所以要定义一个全局的异常处理类,捕获这个异常,并返回给前端处理的结果。

关于全局异常处理更详细用法可以参考我之前写的文章:

@ControllerAdvice
public class CustomExceptionHandler {
    @ExceptionHandler(RestClientException.class)
    public ResponseEntity throwRestException(RestClientException restClientException){
        return new ResponseEntity(restClientException.getMessage(),
                HttpStatus.BAD_REQUEST);
    }
}

(4)测试一下,可以看到异常信息已经返回到前端页面。

原文:SpringBoot - 网络请求模版类RestTemplate使用详解7(异常处理、请求失败处理)



原文出自:www.hangge.com 转载请保留原文链接:https://www.hangge.com/blog/cache/detail_2519.html