继承ZuulFilter打印日志,对gzip数据进行解压和压缩
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.seq.sas.extendmock.service.LoggerService; import com.seq.sas.extendmock.utils.CommonUtils; import org.apache.commons.io.IOUtils; import org.slf4j.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.net.URLDecoder; import java.nio.charset.Charset; import java.util.*; import java.util.zip.*; @Component public class LoggerFilter extends ZuulFilter{ private static final Logger logger = LoggerFactory.getLogger(LoggerFilter.class); @Autowired LoggerService loggerService; @Override public String filterType() { return FilterConstants.POST_TYPE; } @Override public int filterOrder() { return -1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); int status = ctx.getResponseStatusCode(); String responseBody = ""; String path = getHostPath(ctx, request.getServletPath()); String method = request.getMethod(); String reqBody = getReqParams(request); InputStream inputStream = ctx.getResponseDataStream(); try { byte[] bytes; //如果是gzip,需要对数据压缩 if(ctx.getResponseGZipped()) { logger.info(" it is gzipped "); responseBody = StreamUtils.copyToString(new GZIPInputStream(inputStream), Charset.forName("UTF-8")); ByteArrayOutputStream bos = new ByteArrayOutputStream(responseBody.length()); GZIPOutputStream gzip = new GZIPOutputStream(bos); gzip.write(responseBody.getBytes("UTF-8")); gzip.close(); byte[] compressed = bos.toByteArray(); bos.close(); ctx.setResponseDataStream(new ByteArrayInputStream(compressed)); } else { logger.info(" it isn't gzipped "); bytes = StreamUtils.copyToByteArray(inputStream);
responseBody = new String(bytes,"UTF-8"); ctx.setResponseDataStream(new ByteArrayInputStream(bytes)); } } catch (Exception e){ logger.error(e.getMessage(), e); } logger.info("url= {}, method= {},params= {},status= {},response= {}",path,method,reqBody,status,responseBody); return null; } public String getHostPath(RequestContext ctx,String path){ String httpProtocal = ctx.getRouteHost().getProtocol(); String host = ctx.getRouteHost().getHost(); String hostPath = httpProtocal +"://" + host + path; return hostPath; } /* * 获取json格式的请求参数 */ public String getReqParams(HttpServletRequest request){ String contentType = request.getContentType(); String reqBody = ""; if (contentType == null || contentType.contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) { Map<String, String> map = getRequestParam(request); reqBody = CommonUtils.map2Json(map); } else if (contentType != null && contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE)) { reqBody = "{}"; } else if (contentType!= null && contentType.contains(MediaType.APPLICATION_JSON_VALUE)){ reqBody = getRequestBody(request); } return reqBody; } /* * 获取表单请求 */ public Map<String, String> getRequestParam(HttpServletRequest request) { Map<String,String> params = new HashMap<>(); Map<String, String[]> map = request.getParameterMap(); if (map != null && !map.isEmpty()) { for (Map.Entry<String, String[]> entry : map.entrySet()) { String key = entry.getKey(); String value = printArray(entry.getValue()); params.put(key, value); } } return params; } /* * 获取json请求 */ public String getRequestBody(HttpServletRequest request){ String reqBody = ""; try { InputStream inputStream = request.getInputStream(); reqBody = URLDecoder.decode(IOUtils.toString(inputStream, Charset.forName("UTF-8")), "UTF-8"); } catch (IOException e) { e.printStackTrace(); } return reqBody; } String printArray(String[] arr) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < arr.length; i++) { sb.append(arr[i]); if (i < arr.length - 1) { sb.append(","); } } return sb.toString(); } }