RestTemplate请求Api获取不到Response


问题描述

在RestTemplate请求Api时,返回的Response状态码不为200时,RestTemplate会抛出异常,导致我们获取不到Response。原因是RestTemplate中定义了默认异常处理类,在状态码不为200时抛出异常。这并不符合我们的期望,我们希望直接拿到响应体,并且根据我们的业务需要,不同的状态码抛出不同的业务异常。

以下为RestTemplate源码,我们发现他的默认异常处理类只抛出三类异常。

public class DefaultResponseErrorHandler implements ResponseErrorHandler {

	/**
	 * Delegates to {@link #hasError(HttpStatus)} (for a standard status enum value) or
	 * {@link #hasError(int)} (for an unknown status code) with the response status code.
	 * @see ClientHttpResponse#getRawStatusCode()
	 * @see #hasError(HttpStatus)
	 * @see #hasError(int)
	 */
	@Override
	public boolean hasError(ClientHttpResponse response) throws IOException {
		int rawStatusCode = response.getRawStatusCode();
		HttpStatus statusCode = HttpStatus.resolve(rawStatusCode);
		return (statusCode != null ? hasError(statusCode) : hasError(rawStatusCode));
	}

    ......

	/**
	 * Handle the error based on the resolved status code.
	 *
	 * <p>The default implementation delegates to
	 * {@link HttpClientErrorException#create} for errors in the 4xx range, to
	 * {@link HttpServerErrorException#create} for errors in the 5xx range,
	 * or otherwise raises {@link UnknownHttpStatusCodeException}.
	 *
	 * @since 5.0
	 * @see HttpClientErrorException#create
	 * @see HttpServerErrorException#create
	 */
	protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
		String statusText = response.getStatusText();
		HttpHeaders headers = response.getHeaders();
		byte[] body = getResponseBody(response);
		Charset charset = getCharset(response);
		String message = getErrorMessage(statusCode.value(), statusText, body, charset);

		switch (statusCode.series()) {
			case CLIENT_ERROR:
				throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset);
			case SERVER_ERROR:
				throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset);
			default:
				throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset);
		}
	}

    ......

}

解决方案

这时候我们需要使用RestTemplate中的自定义异常处理类,使得任何状态码都不会抛出异常,这样我们就可以在自己的系统中根据Response的状态码处理异常。

自定义异常处理类
    /**
     * 忽略异常处理器
     * 该异常处理器会忽略RestTemplate中的异常状态码
     */
    public static class IgnoreErrorHandler implements ResponseErrorHandler {
        /**
         * 忽略所有异常
         *
         * @param response the response to inspect
         * @return false
         */
        @Override
        public boolean hasError(@NotNull ClientHttpResponse response) {
            return false;
        }

        @Override
        public void handleError(@NotNull ClientHttpResponse response) {

        }
    }
自定义异常处理类注册
    // 创建RestTemplate实例
    RestTemplate restTemplate = new RestTemplate();
    // 设置自定义异常处理
    restTemplate.setErrorHandler(new IgnoreErrorHandler());

设置了自定义异常处理器之后,我们就可以根据状态码来进行异常处理了。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值