RestTemplate请求返回400错误时如何执行后续代码并设置响应数据
问题原因
默认RestTemplate使用DefaultResponseErrorHandler处理响应,会将4xx、5xx状态码的响应统一判定为请求错误,直接抛出HttpClientErrorException(4xx)或HttpServerErrorException(5xx),因此会直接进入catch块跳过后续赋值逻辑。不需要额外设置标志变量,调整错误处理逻辑即可实现需求。
实现方案
提供两种可选方案,按需选择即可:
方案1:自定义全局响应错误处理器(推荐)
修改RestTemplate的错误处理规则,让4xx类响应不抛出异常,直接返回ResponseEntity对象,后续业务逻辑无需调整。
首先自定义错误处理器:
public class CustomResponseErrorHandler extends DefaultResponseErrorHandler { @Override public boolean hasError(ClientHttpResponse response) throws IOException { // 仅将5xx状态码判定为错误抛出异常,4xx正常返回 HttpStatus.Series series = HttpStatus.Series.resolve(response.getStatusCode().value()); return series == HttpStatus.Series.SERVER_ERROR; } }
然后在初始化RestTemplate的时候注入这个处理器:
@Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new CustomResponseErrorHandler()); return restTemplate; }
调整后即使接口返回400也能正常拿到responseEntity对象,后续赋值逻辑可以正常执行。
方案2:在catch块中手动解析异常响应(无需修改全局RestTemplate配置)
如果不想改动全局RestTemplate的配置,可以在捕获异常时从HttpClientErrorException中提取响应状态、响应体等信息,手动赋值到response对象,再把通用的赋值逻辑提取到公共位置执行,调整后的业务代码示例:
ResponseEntity<ClientResponse> responseEntity = null; try { responseEntity = this.getRestTemplate().exchange(API_URL, HttpMethod.POST, entity, ClientResponse.class); response.setResponseEntity(responseEntity); } catch (HttpClientErrorException e) { // 4xx类异常手动解析响应 LOG.error("请求返回4xx状态码:{}", e.getMessage()); // 从异常中提取状态码、响应体等信息构造ClientResponse,按需补充字段 ClientResponse errorClientResponse = gson.fromJson(e.getResponseBodyAsString(), ClientResponse.class); response.setResponseEntity(new ResponseEntity<>(errorClientResponse, e.getStatusCode())); } catch (Exception e) { // 其他非HTTP响应类异常统一处理 LOG.error("服务调用发生异常:{}", e.getMessage()); } // 通用赋值逻辑统一放到try-catch外部,不管请求成功失败都会执行 response.setValue(inputRequest.getValue()); response.setEndTime(LocalDateTime.now()); response.setRequestPayload(gson.toJson(inputRequest)); response.setHttpMethod(HttpMethod.POST); response.setRequestHeaders(entity.getHeaders().toSingleValueMap()); return response;
内容的提问来源于stack exchange,提问作者Dead pool
相关产品推荐
相关产品推荐

