RestTemplate如何获取HTTP状态码

 更新时间:2026年01月06日 09:21:37   作者:搬甎小犟  
文章介绍了使用RestTemplate请求接口并处理HTTP状态码的方法,为了解决默认处理器抛出异常的问题,建议自定义ResponseErrorHandler,自定义处理器不会抛出异常,从而可以获取ResponseEntity对象并获取HTTP状态码

背景

  • 使用RestTemplate请求特定接口,并根据获取的HTTP状态码进行具体业务操作。
@RestController
public class RestfulController {
    private RestTemplate restTemplate = new RestTemplate();

    @GetMapping("/test1")
    public void test1(HttpServletResponse response) {
        response.setStatus(403);
    }

    @GetMapping("/test2")
    public void test2() {
        ResponseEntity responseEntity = restTemplate.exchange("http://127.0.0.1:8080/test1", HttpMethod.GET, new HttpEntity<String>(null, new HttpHeaders()), String.class);
        int code = responseEntity.getStatusCodeValue();
        // 具体业务操作...
    }
}

报错

​org.springframework.web.client.HttpClientErrorException$Forbidden: 403 null

解决

  • 如果想要使用responseEntity.getStatusCodeValue()等,需要先为RestTemplate对象设置ResponseErrorHandler。
  • 需要注意代码并不符合平常的开发规范,只是为了实现效果。
@RestController
public class RestfulController {
    private RestTemplate restTemplate = new RestTemplate();

    @GetMapping("/test1")
    public void test1(HttpServletResponse response) {
        response.setStatus(403);
    }

    @GetMapping("/test2")
    public void test2() {
        restTemplate.setErrorHandler(new RestfulController.ErrorHandler());
        ResponseEntity responseEntity = restTemplate.exchange("http://127.0.0.1:8080/test1", HttpMethod.GET, new HttpEntity<String>(null, new HttpHeaders()), String.class);
        int code = responseEntity.getStatusCodeValue();
        // 业务处理...
    }

    static class ErrorHandler implements ResponseErrorHandler {

        @Override
        public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
            if (200 == clientHttpResponse.getRawStatusCode()) {
                return false;
            }
            return true;
        }

        @Override
        public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
            // 处理Error...
        }
    }
}

原因

  • RestTemplate
public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
	...
    private ResponseErrorHandler errorHandler;
    ...

    public RestTemplate() {
        ...
        // 默认的ResponseErrorHandler
        this.errorHandler = new DefaultResponseErrorHandler();
        ...
    }

	...

	@Nullable
    protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
        Assert.notNull(url, "URI is required");
        Assert.notNull(method, "HttpMethod is required");
        ClientHttpResponse response = null;

        Object var14;
        try {
            ClientHttpRequest request = this.createRequest(url, method);
            if (requestCallback != null) {
                requestCallback.doWithRequest(request);
            }

            response = request.execute();
            
            // 处理Response, 这里如果抛出异常,就不会返回ResponseEntity对象
            this.handleResponse(url, method, response);
            
            var14 = responseExtractor != null ? responseExtractor.extractData(response) : null;
        } catch (IOException var12) {
            String resource = url.toString();
            String query = url.getRawQuery();
            resource = query != null ? resource.substring(0, resource.indexOf(63)) : resource;
            throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + resource + "\": " + var12.getMessage(), var12);
        } finally {
            if (response != null) {
                response.close();
            }

        }

        return var14;
    }

	protected void handleResponse(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
        ResponseErrorHandler errorHandler = this.getErrorHandler();
        boolean hasError = errorHandler.hasError(response);
        if (this.logger.isDebugEnabled()) {
            try {
                int code = response.getRawStatusCode();
                HttpStatus status = HttpStatus.resolve(code);
                this.logger.debug("Response " + (status != null ? status : code));
            } catch (IOException var8) {
            }
        }

        if (hasError) {
        	// 处理Http错误码
            errorHandler.handleError(url, method, response);
        }

    }

	...
}
  • DefaultResponseErrorHandler
public class DefaultResponseErrorHandler implements ResponseErrorHandler {
    public DefaultResponseErrorHandler() {
    }

    public boolean hasError(ClientHttpResponse response) throws IOException {
        int rawStatusCode = response.getRawStatusCode();
        HttpStatus statusCode = HttpStatus.resolve(rawStatusCode);
        return statusCode != null ? this.hasError(statusCode) : this.hasError(rawStatusCode);
    }

    protected boolean hasError(HttpStatus statusCode) {
        return statusCode.isError();
    }

    protected boolean hasError(int unknownStatusCode) {
        Series series = Series.resolve(unknownStatusCode);
        return series == Series.CLIENT_ERROR || series == Series.SERVER_ERROR;
    }

    public void handleError(ClientHttpResponse response) throws IOException {
        HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
        if (statusCode == null) {
            throw new UnknownHttpStatusCodeException(response.getRawStatusCode(), response.getStatusText(), response.getHeaders(), this.getResponseBody(response), this.getCharset(response));
        } else {
            this.handleError(response, statusCode);
        }
    }

    protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException {
        String statusText = response.getStatusText();
        HttpHeaders headers = response.getHeaders();
        byte[] body = this.getResponseBody(response);
        Charset charset = this.getCharset(response);
        switch(statusCode.series()) {
        case CLIENT_ERROR:
            throw HttpClientErrorException.create(statusCode, statusText, headers, body, charset);
        case SERVER_ERROR:
            throw HttpServerErrorException.create(statusCode, statusText, headers, body, charset);
        default:
            throw new UnknownHttpStatusCodeException(statusCode.value(), statusText, headers, body, charset);
        }
    }
    
    ...
}
  • RestTemplate中的getForEntity(…)、 getForObject(…)、exchange(…)和delete(…)等方法最终都是调用doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor responseExtractor)方法。
  • 从源代码可以看出来默认的处理器DefaultResponseErrorHandler,最后会抛出三种异常:HttpClientErrorException、HttpServerErrorException、UnknownHttpStatusCodeException。所以在得到ResponseEntity返回值之前,就有异常抛出。
  • 可以自定义错误处理器,自定义的处理器并没有抛出异常,所以也就可以返回ResponseEntity对象,并通过该对象的getStatusCodeValue()方法获取HTTP状态码。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 分析讲解SpringMVC注解配置如何实现

    分析讲解SpringMVC注解配置如何实现

    这篇文章主要介绍了本文要介绍用注解方式代替web.xml与SpringMVC的配置文件,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • 关于idea刚打开时疯狂报错的问题

    关于idea刚打开时疯狂报错的问题

    这篇文章主要介绍了关于idea刚打开时疯狂报错的问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • java中JDeps命令使用

    java中JDeps命令使用

    jdeps是一个Java类依赖分析工具,用于分析Java应用程序的依赖情况,包括类、包、模块以及JDK内部API的使用,本文就来详细的介绍一下,感兴趣的可以了解一下
    2024-09-09
  • Java实现不同的类的属性之间相互赋值

    Java实现不同的类的属性之间相互赋值

    今天小编就为大家分享一篇关于Java实现不同的类的属性之间相互赋值,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • java Swing实现五子棋游戏

    java Swing实现五子棋游戏

    这篇文章主要为大家详细介绍了java Swing实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • java 实现KMP算法

    java 实现KMP算法

    这篇文章主要介绍了java 如何实现KMP算法,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-12-12
  • SpringBoot 回滚操作的几种实现方式

    SpringBoot 回滚操作的几种实现方式

    回滚操作是一种常见的操作,用于撤销之前执行的操作,本文主要介绍了SpringBoot回滚操作的几种实现方式,包含基于异常类型的回滚、基于自定义逻辑的回滚和基于数据库状态的回滚,感兴趣的可以了解一下
    2024-03-03
  • Java实现添加、验证PDF数字签名的方法示例

    Java实现添加、验证PDF数字签名的方法示例

    在设置文档内容保护的方法中,除了对文档加密、添加水印外,应用数字签名也是一种有效防伪手段。本文就使用Java实现添加、验证PDF数字签名,感兴趣的可以了解一下
    2021-07-07
  • Java long 转成 String的实现

    Java long 转成 String的实现

    这篇文章主要介绍了Java long 转成 String的实现,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • SpringBoot整合RedisTemplate实现缓存信息监控的基本操作

    SpringBoot整合RedisTemplate实现缓存信息监控的基本操作

    SpringBoot中的 redistemplate 是一个用于操作 Redis 数据库的高级模板类,它提供了一组方法,可以方便地执行常见的 Redis 操作,如存储、检索和删除数据,本文给大家介绍了SpringBoot整合RedisTemplate实现缓存信息监控的基本操作,需要的朋友可以参考下
    2025-02-02

最新评论