java okhttp日志与工具类封装
目录
- pom依赖
- 日志拦截器
- 工具类简单封装
pom依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>3.14.9</version>
</dependency>
日志拦截器
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okio.Buffer;
import okio.BufferedSource;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
@Slf4j
public class CustomHttpLoggingInterceptor implements Interceptor {
private static final String CONTENT_TYPE = "application/json";
private Level level;
public CustomHttpLoggingInterceptor(Level level) {
this.level = level;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
return logInfo(chain);
}
private Response logInfo(Chain chain) throws IOException {
String traceId = getUUID();
Request request = chain.request();
String method = request.method();
String uri = request.url().uri().toString();
RequestBody body = request.body();
print(String.format("%s --> %s %s", traceId, method, uri));
logRequestHeaders(request, traceId);
String bodyStr = null;
long bodyLength = 0;
String contentType = null;
if (body != null) {
bodyLength = body.contentLength();
if (bodyLength > 0) {
contentType = body.contentType().toString();
if (contentType.startsWith(CONTENT_TYPE)) {
Buffer buffer = new Buffer();
body.writeTo(buffer);
bodyStr = buffer.readString(StandardCharsets.UTF_8);
}
}
}
if (body != null) {
print(String.format("%s --> Content-Type %s Content-Length %s", traceId, contentType, bodyLength));
print(String.format("%s --> request body%n%s", traceId, bodyStr));
}
long startNs = System.nanoTime();
Response response = chain.proceed(request);
long timeMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
boolean successful = response.isSuccessful();
if (successful) {
logResponseHeaders(response, traceId);
}
print(String.format("%s <-- %s %sms %n%s", traceId, response.code(), timeMillis, getBodyCopy(response)));
return response;
}
private void logRequestHeaders(Request request, String traceId) {
Headers headers = request.headers();
for (int i = 0; i < headers.size(); i++) {
print(String.format("%s --> header %s %s", traceId, headers.name(i), headers.value(i)));
}
}
private void logResponseHeaders(Response response, String traceId) {
Headers headers = response.headers();
for (int i = 0; i < headers.size(); i++) {
print(String.format("%s <-- header %s %s", traceId, headers.name(i), headers.value(i)));
}
}
private String getBodyCopy(Response response) throws IOException {
MediaType mediaType = response.body().contentType();
if (ObjectUtil.isNotNull(mediaType) && !mediaType.toString().startsWith(CONTENT_TYPE)) {
return StrUtil.EMPTY;
}
BufferedSource source = response.body().source();
source.request(Long.MAX_VALUE);
return source.getBuffer().clone().readString(StandardCharsets.UTF_8);
}
public void setLevel(Level level) {
this.level = level;
}
private static String getUUID() {
return UUID.fastUUID().toString().replaceAll("-", "");
}
private void print(String str) {
log.info(str);
}
}
日志级别
package com.kexie.common.util;
import java.util.HashMap;
import java.util.Map;
public enum Level {
/**
* No logs.
*/
NONE,
/**
* --> currentTime , method, uri , userId , sessionId ,stackTrace
* <-- currentTime, httpStatus, method, uri
*/
INFO,
/**
* --> currentTime , method , uri , userId , sessionId , headers , body ,stackTrace
* <-- currentTime , httpStatus , method , uri , headers , body
*/
DEBUG;
static Map<String, Level> map = new HashMap<>() {
private static final long serialVersionUID = -2873590923344392083L;
{
put("NONE",NONE);
put("INFO",INFO);
put("DEBUG",DEBUG);
}
};
public static Level nameOf(String name) {
return map.get(name);
}
}
工具类简单封装
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.esotericsoftware.reflectasm.FieldAccess;
import com.kexie.common.entity.Model;
import com.kexie.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
@Slf4j
public class OkHttpUtils {
public static final MediaType MEDIA_TYPE = MediaType.parse("application/json;charset=UTF-8");
private static OkHttpClient okHttpClient;
/**
* okhttp3请求日志
*/
private static final CustomHttpLoggingInterceptor LOGGING_INTERCEPTOR_INSTANCE = getHttpLoggingInterceptor();
private static CustomHttpLoggingInterceptor getHttpLoggingInterceptor() {
return new CustomHttpLoggingInterceptor(Level.INFO);
}
/**
* 双重检查锁构造单例
*/
public static OkHttpClient getOkHttpSingletonInstance() {
if (okHttpClient == null) {
synchronized (OkHttpClient.class) {
if (okHttpClient == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(LOGGING_INTERCEPTOR_INSTANCE);
okHttpClient = builder.build();
}
}
}
return okHttpClient;
}
/**
* 发起请求
*/
public static Response doRequest(Request request) throws IOException {
return getOkHttpSingletonInstance().newCall(request).execute();
}
public static <T> T doRequest(Request request, TypeReference<T> typeReference) throws IOException {
Response response = doRequest(request);
boolean successful = response.isSuccessful();
String jsonStr = response.body().string();
if (successful) {
return JSON.parseObject(jsonStr, typeReference);
}
throw exceptionHandle(jsonStr);
}
private static ServiceException exceptionHandle(String errorMsg) {
ServiceException serviceException = new ServiceException("99999");
HashMap<Object, Object> errorMsgMap = new HashMap<>(1);
errorMsgMap.put("errorMsg", errorMsg);
serviceException.setData(errorMsgMap);
return serviceException;
}
}
touch fish

浙公网安备 33010602011771号