您的位置:

如何有效处理HTTP请求异常

一、HTTP请求异常的种类

在处理HTTP请求异常之前,我们需要清楚的了解HTTP请求异常的种类。HTTP请求异常包括但不限于:

1、网络异常:如DNS解析失败、网络连接超时等


try{
    httpclient.execute(httpget)
}catch(UnknownHostException | ConnectTimeoutException e){
    //处理网络异常
}

2、服务器异常:如响应码不是200、服务器返回的JSON信息格式不规范等


HttpResponse response = httpclient.execute(httpget);
if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
    //处理服务器异常
}

3、业务异常:如用户登录信息错误、订单不存在等


HttpResponse response = httpclient.execute(httpget);
String result = EntityUtils.toString(response.getEntity());
ResultDTO resultDTO = JSON.parseObject(result, ResultDTO.class);
if(resultDTO.getCode() != ResultCode.SUCCESS.getCode()){
    //处理业务异常
}

二、如何有效处理HTTP请求异常

在开发过程中,我们需要遵循以下几个原则来处理HTTP请求异常:

1、明确异常的类型,合理区分异常的处理方式。

2、充分利用HTTP中请求响应的状态码和异常信息,特别是在服务器异常时需要充分利用返回的错误信息来解决问题。

3、通过记录日志的方式,快速定位问题所在。

4、业务异常需要使用自定义异常来处理,一方面能够更好的维护异常逻辑,另一方面能够在异常处理层面区分业务异常与其它异常。

三、HTTP请求异常处理的最佳实践

1、封装工具类。将HTTP请求的重试、重定向、异常处理封装到工具类中,使得代码更简洁,维护更方便。


public static String get(String url) {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    String result = null;
    HttpGet httpGet = new HttpGet(url);
    try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                result = EntityUtils.toString(entity, "UTF-8");
            }
        } else {
            throw new RuntimeException("HTTP请求异常!");
        }
    } catch (IOException e) {
        throw new RuntimeException("网络异常!");
    } finally {
        try {
            httpClient.close();
        } catch (IOException e) {
            throw new RuntimeException("关闭httpClient异常!");
        }
    }
    return result;
}

2、自定义异常。通过自定义异常来对HTTP请求异常进行分类处理。


public class BusinessException extends RuntimeException {

    private static final long serialVersionUID = 1L;
    private Integer code;
    private String message;

    public BusinessException(ResultCode resultCode) {
        super(resultCode.getMessage());
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

3、日志记录。在处理异常时,需要及时记录错误信息,方便进行问题定位和修复。


private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

public static String get(String url) {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    String result = null;
    HttpGet httpGet = new HttpGet(url);
    try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                result = EntityUtils.toString(entity, "UTF-8");
            }
        } else {
            logger.error("请求失败,url: {}, statusCode: {}", url, response.getStatusLine().getStatusCode());
            throw new BusinessException(ResultCode.HTTP_REQUEST_ERROR);
        }
    } catch (IOException e) {
        logger.error("请求异常,url: {}", url, e);
        throw new BusinessException(ResultCode.NETWORK_ERROR);
    } finally {
        try {
            httpClient.close();
        } catch (IOException e) {
            logger.error("关闭httpClient异常", e);
            throw new BusinessException(ResultCode.HTTP_CLIENT_CLOSE_ERROR);
        }
    }
    return result;
}