import com.github.benmanes.caffeine.cache.Cache;
import com.smdt.cache.EhcacheConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Enumeration;
@Slf4j
public class ByteInterceptor extends HandlerInterceptorAdapter {
@Resource
Cache<String, Object> caffeineCache;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException, ServletException {
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
try {
long bytesRead = bytesRead(request);
//log.info("=====request bytesRead====:" + bytesRead);
long bytesWritten = bytesWritten(response);
//log.info("=====response bytesWritten====:" + bytesWritten);
Enumeration headerNames = request.getHeaderNames();
long length = 0;
while (null != headerNames && headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);
length = length + key.length() + value.length();
}
Collection<String> responseHeaderNames = response.getHeaderNames();
long headerLength = 0;
for (String name : responseHeaderNames) {
String value = response.getHeader(name);
headerLength = headerLength + name.length() + value.length();
}
//log.info("=====request header length====:" + length);
//log.info("=====response header length===:" + headerLength);
Long readCache = (Long) caffeineCache.getIfPresent(EhcacheConfig.KEY_BYTE_READ);
caffeineCache.put(EhcacheConfig.KEY_BYTE_READ, (readCache == null ? 0L : readCache) + bytesRead + length);
Long writtenCache = (Long) caffeineCache.getIfPresent(EhcacheConfig.KEY_BYTE_WRITTEN);
caffeineCache.put(EhcacheConfig.KEY_BYTE_WRITTEN, (writtenCache == null ? 0L : writtenCache) + bytesWritten + headerLength);
} catch (Exception e) {
e.printStackTrace();
}
}
private long bytesWritten(HttpServletResponse response) {
long bytesWritten = 0;
try {
Field response1 = response.getClass().getDeclaredField("response");
response1.setAccessible(true);
Object resp2 = response1.get(response);
Field coyoteResponse = resp2.getClass().getDeclaredField("coyoteResponse");
coyoteResponse.setAccessible(true);
org.apache.coyote.Response resp3 = (org.apache.coyote.Response) coyoteResponse.get(resp2);
bytesWritten = resp3.getBytesWritten(true);
} catch (Exception e) {
}
return bytesWritten;
}
private long bytesRead(HttpServletRequest request) {
long bytesRead = 0;
Class<?> clazz = request.getClass();
Object obj = request;
try {
if (request instanceof StandardMultipartHttpServletRequest) {
//上传文件
Class<?> superclass = request.getClass().getSuperclass();
Class<?> superclass1 = superclass.getSuperclass();
Class<?> superclass2 = superclass1.getSuperclass();
Field declaredField = superclass2.getDeclaredField("request");
declaredField.setAccessible(true);
Object request1 = declaredField.get(request);
clazz = request1.getClass();
obj = request1;
}
Field declaredField = clazz.getDeclaredField("request");
declaredField.setAccessible(true);
Object request1 = declaredField.get(obj);
Field field = request1.getClass().getDeclaredField("coyoteRequest");
field.setAccessible(true);
org.apache.coyote.Request coyoteRequest = (org.apache.coyote.Request) field.get(request1);
bytesRead = coyoteRequest.getBytesRead();
} catch (Exception e) {
}
return bytesRead;
}
}
org.apache.coyote.Request coyoteRequest
org.apache.coyote.Response coyoteResponse
公司项目使用spring boot,默认使用tomcat容器,而HttpServletRequest、HttpServletResponse中最低层都有以上的类,org.apache.coyote.Request.getBytesRead()和org.apache.coyote.Response.getBytesWritten(true)就可以获取对应的读/写字节数,之后再计算下头的长度就可以了