RestTemplate异常信息(4xx和5xx)处理

在日常开发中经常会用到RestTemplate这一客户端进行访问其他的接口时,经常会遇到异常处理的问题,关于RestTemplate的异常处理,主要会用到一个接口org.springframework.web.client.ResponseErrorHandler,源码如下:

public interface ResponseErrorHandler {
          
   
  // 判断是否有异常
	boolean hasError(ClientHttpResponse response) throws IOException;
  // 如果有问题,进入这个方法,处理问题
	void handleError(ClientHttpResponse response) throws IOException;
}

ResponseErrorHandler 会根据RestTemplate的响应码来判断返回结果是否有异常。 接下来看一下该接口的实现类DefaultResponseErrorHandler,如下:

// 根据http code判断是否有问题
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
          
   
	HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
	return (statusCode != null && hasError(statusCode));
}

// 如果返回的http code是标准的4xx, 5xx,那么就认为有问题了
protected boolean hasError(HttpStatus statusCode) {
          
   
	return (statusCode.series() == HttpStatus.Series.CLIENT_ERROR ||
			statusCode.series() == HttpStatus.Series.SERVER_ERROR);
}

// 接下来是异常的处理
@Override
public void handleError(ClientHttpResponse response) throws IOException {
          
   
		HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
		if (statusCode == null) {
          
   
			byte[] body = getResponseBody(response);
			String message = getErrorMessage(response.getRawStatusCode(),
					response.getStatusText(), body, getCharset(response));
			throw new UnknownHttpStatusCodeException(message,
					response.getRawStatusCode(), response.getStatusText(),
					response.getHeaders(), body, getCharset(response));
		}
		handleError(response, statusCode);
}
protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
          
   
	switch (statusCode.series()) {
          
   
		case CLIENT_ERROR:
			throw new HttpClientErrorException(statusCode, response.getStatusText(),
					response.getHeaders(), getResponseBody(response), getCharset(response));
		case SERVER_ERROR:
			throw new HttpServerErrorException(statusCode, response.getStatusText(),
					response.getHeaders(), getResponseBody(response), getCharset(response));
		default:
			throw new UnknownHttpStatusCodeException(statusCode.value(), response.getStatusText(),
					response.getHeaders(), getResponseBody(response), getCharset(response));
	}
}

接下来说明一下如何使用该接口类,这里主要有三种方式: 方式一:给RestTemplate对象设置该属性

RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
          
   
    @Override
    protected boolean hasError(HttpStatus statusCode) {
          
   
        return super.hasError(statusCode);
    }

    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
          
   
    	super.handleError(response);
    }
});

方式二:自定义一个类来实现ResponseErrorHandler接口

public class Test implements ResponseErrorHandler {
          
   

@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
          
   
	return false;
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
          
   

	}
}

方式三:直接使用try..catch来处理

RestTemplate restTemplate = new RestTemplate();
try{
          
   
	HttpEntity<String> ans=restTemplate.exchange(.......);
} catch (HttpClientErrorException e) {
          
   
	throw new xxxxException(HttpStatus.UNAUTHORIZED,JSON.parseObject(e.getResponseBodyAsString()).get("message").toString());
} catch (HttpServerErrorException e) {
          
   
	throw new xxxxException(HttpStatus.INTERNAL_SERVER_ERROR,JSON.parseObject(e.getResponseBodyAsString()).get("message").toString());
} catch (UnknownHttpStatusCodeException e) {
          
   
	throw new xxxxException(HttpStatus.INTERNAL_SERVER_ERROR,JSON.parseObject(e.getResponseBodyAsString()).get("message").toString());
}
// xxxxException代指自定义类型异常
经验分享 程序员 微信小程序 职场和发展