OkHttp3是由Square贡献的HTTP客户端框架,主要用在Andorid中,但是由于其易用的API、强大的功能、请求的快速等特点,也被大量采用在后端开发领域。本系列文章讲述OkHttp3的基本使用、OkHttp3的高级功能以及OkHttp3源码的解析等,请持续关注。
本篇文章是此系列的第三篇。
简介#
okhttp3-fast-spring-boot-starter是笔者开发的一个HTTP网络调用库,封装了okhttp3,按照Spring Boot Starter标准开发,可以帮助我们快速的在Spring Boot项目中使用okhttp3。同时okhttp3-fast-spring-boot-starter提供了方便易用的API、好用的辅助功能,让开发人员效率倍增、心情舒畅。
项目已在Github公布,并在Maven中央仓库发布。项目的具体使用方法已在Github中详细介绍,对于想学习okhttp3框架的同学,本项目有很多使用okhttp3的示例,可作为案列参考,想要试用的同学快来吧。
详细介绍#
日志拦截器#
okhttp3-fast-spring-boot-starter使用okhttp3提供的拦截器功能开发了日志拦截器,用于打印请求过程的详细信息,方便使用人员诊断项目。
Copy
/**
* 日志拦截器
*/
public class LoggingInterceptor implements Interceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingInterceptor.class);
private final Charset UTF8 = Charset.forName("UTF-8");
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
RequestBody requestBody = request.body();
String sendBody = "";
if (requestBody != null) {
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
Charset charset = UTF8;
MediaType contentType = requestBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
sendBody = buffer.readString(charset == null? UTF8 : charset);
}
LOGGER.debug("\n request method : {} \n request url: {} \n request headers: {} \n request body: {}",
request.method(), URIUtils.urlDecode(request.url().toString()), request.headers(), sendBody);
long requestStartNanoTime = System.nanoTime();
Response response = chain.proceed(request);
long requestEndNanoTime = System.nanoTime();
double usedMillsTime = (requestEndNanoTime - requestStartNanoTime) / Math.pow(10, 6);
ResponseBody responseBody = response.body();
String receiveBody = "";
if (responseBody != null) {
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE);
Buffer buffer = source.getBuffer();
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
receiveBody = buffer.clone().readString(charset == null? UTF8 : charset);
}
LOGGER.debug("\n response url: {} \n response time: {} millseconds \n response code: {} \n request headers: {} \n " +
"request body: {} \n response headers: {} \n response body: {}",
URIUtils.urlDecode(response.request().url().toString()), String.format("%.2f", usedMillsTime),
response.code(), request.headers(), sendBody, response.headers(), receiveBody);
return response;
}
}
自动认证机制#
okhttp3-fast-spring-boot-starter使用okhttp3提供的认证功能开发了自动认证机制,目前支持对Baisc Auth和Digest Auth的认证。
public class AuthAuthenticator implements Authenticator {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthAuthenticator.class);
private final Charset UTF8 = Charset.forName("UTF-8");
@Override
public Request authenticate(Route route, Response response) throws IOException {
if (AuthConfig.isStatus()) {
String responseAuth = response.header("WWW-Authenticate");
if (responseAuth == null || responseAuth.length() <= 0) {
return null;
}
String authType = WWWAuthParse.authType(responseAuth);
if ("Basic".equalsIgnoreCase(authType)) {
if (!StringUtils.isEmpty(AuthConfig.getBasicUsername()) && !StringUtils.isEmpty(AuthConfig.getBasicPassword())) {
String basicAuth = Credentials.basic(AuthConfig.getBasicUsername(), AuthConfig.getBasicPassword());
return response.request().newBuilder().addHeader("Authorization", basicAuth).build();
}
return null;
} else if ("Digest".equalsIgnoreCase(authType)) {
if (!StringUtils.isEmpty(AuthConfig.getDigestUsername()) && !StringUtils.isEmpty(AuthConfig.getDigestPassword())) {
Map<String, String> digestAuthMap = new HashMap<>();
try {
digestAuthMap = WWWAuthParse.parseDigestAuthenticateHeader(responseAuth);
} catch (Exception e) {
LOGGER.error("处理Digest认证,解析Response Header WWW-Authenticate [{}] 出错", responseAuth);
return null;
}
digestAuthMap.put("username", AuthConfig.getDigestUsername());
digestAuthMap.put("password", AuthConfig.getDigestPassword());
digestAuthMap.put("uri", new URL(response.request().url().toString()).getPath());
digestAuthMap.put("method", response.request().method());
if (response.request().body() != null) {
Buffer buffer = new Buffer();
response.request().body().writeTo(buffer);
Charset charset = UTF8;
MediaType contentType = response.request().body().contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
String requestBody = buffer.readString(charset == null? UTF8 : charset);
digestAuthMap.put("body", requestBody);
} else {
digestAuthMap.put("body", "");
}
String authorization = WWWAuthParse.assembleDigestAuthorization(digestAuthMap);
if (!StringUtils.isEmpty(authorization)) {
return response.request().newBuilder().addHeader("Authorization", authorization).build();
}
}
return null;
} else {
return null;
}
}
return null;
}
}
小结#
本篇文章介绍了笔者开发的okhttp3-fast-spring-boot-starter框架,介绍了该框架的基本功能。除了上述功能点外,okhttp3-fast-spring-boot-starter还提供了很多其它功能,喜欢该框架的同学可以在Github点击下star,对该框架有想法或者不同意见的同学,可以在本篇文章下评论留言、在Github上提出Issue或者通过笔者在Github首页留下的邮箱地址联系笔者。
作者:weegee