一、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;
}