import com.alibaba.fastjson.JSONObject; import com.idoipo.infras.gateway.open.model.InvokeLogModel; import com.idoipo.infras.gateway.open.service.IInvokeLogService; import com.idoipo.infras.gateway.open.utils.MultiPartFormDateToJson; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.Date; import java.util.Map; /** * Create by liping on 2018/9/11 * 接口调用日志记录过滤器 */ @Component public class LogRecodePostFilter extends ZuulFilter { private static final Logger logger = LoggerFactory.getLogger(LogRecodePostFilter.class); @Autowired IInvokeLogService invokeLogService; @Override public String filterType() { return FilterConstants.POST_TYPE;//要打印返回信息,必须得用"post" } @Override public int filterOrder() { return FilterConstants.PRE_DECORATION_FILTER_ORDER + 2; } @Override public boolean shouldFilter() { RequestContext context = RequestContext.getCurrentContext(); Boolean isSuccess = (boolean) context.get("isSuccess"); return isSuccess; } @Override public Object run() { try { logger.info("进入日志记录过滤器"); RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); InputStream in = request.getInputStream(); String method = request.getMethod(); String interfaceMethod = request.getServletPath(); //logger.info("请求方法method={},url={}",method,interfaceMethod); String reqBody = StreamUtils.copyToString(in, Charset.forName("UTF-8")); int user = 0; String invokeUser = ""; if ("GET".equals(method.toUpperCase())) { Map<String, String[]> map = request.getParameterMap(); // 打印请求url参数 if (map != null) { StringBuilder sb = new StringBuilder(); sb.append("{"); for (Map.Entry<String, String[]> entry : map.entrySet()) { String key = entry.getKey(); String value = printArray(entry.getValue()); sb.append("[" + key + "=" + value + "]"); if ("user".equals(key)) { invokeUser = value; } else if ("userFlag".equals(key)) { user = Integer.parseInt(value); } } sb.append("}"); reqBody = sb.toString(); //logger.info("reqBody ={}" + reqBody); } } else if ("POST".equals(method.toUpperCase())) { //打印请求json参数 if (reqBody != null) { String conType = request.getHeader("content-type"); //post请求目前获取userFlag,user参数只支持multipart/form-data,application/json,对于其他方式不记录用户信息 if (conType.contains("multipart/form-data") || conType.contains("application/json")) { if (conType.contains("multipart/form-data")) { reqBody = MultiPartFormDateToJson.formDateToJson(reqBody); } //默认content-type传json-->application/json Object userObject; Object invokeUserObject; JSONObject jsonObject = JSONObject.parseObject(reqBody); userObject = jsonObject.get("userFlag"); if (null != userObject) { user = Integer.parseInt(userObject.toString()); } else { logger.warn("当前请求缺少userFlag"); } invokeUserObject = jsonObject.get("user"); if (null != userObject) { invokeUser = invokeUserObject.toString(); } else { logger.warn("当前请求缺少user"); } //logger.info("reqBody:={}" + reqBody); } } } // 打印response InputStream out = ctx.getResponseDataStream(); String outBody = StreamUtils.copyToString(out, Charset.forName("UTF-8")); boolean result = false; if (outBody != null && "" != outBody) { JSONObject jsonObject = JSONObject.parseObject(outBody); Object dataFlagObject = jsonObject.get("dataFlag"); if (null != dataFlagObject) { int flag = Integer.parseInt(dataFlagObject.toString()); if (flag == 1) { result = true; } } //logger.info("响应参数:={}" + outBody); } //必须重新写入流//重要!!! ctx.setResponseBody(outBody); InvokeLogModel logModel = new InvokeLogModel(); logModel.setUid(user); logModel.setInvokeUser(invokeUser); logModel.setInterfaceName(interfaceMethod); logModel.setInterfaceMethod(method); logModel.setInvokeStartTime(new Date()); logModel.setInvokeEndTime(null); logModel.setRequestParam(reqBody); logModel.setResponseResult(result); logModel.setResponseBody(outBody); invokeLogService.insertInvokerLog(logModel); } catch (IOException e) { logger.error("LogRecode IO异常", e); } return null; } 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(); } }
当是post请求的格式不是application/json格式,而是multipart/form-data格式时,数据不能直接转json对象,需要进行匹配,可以使用如下工具类
import com.alibaba.fastjson.JSON; import org.apache.commons.lang.StringUtils; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Optional; /** * 当数据 * Create by liping on 2018/9/14 */ public class MultiPartFormDateToJson { public static Map<String, String> toMap(String params) { Map<String, String> map = new HashMap<>(); //获得分隔符 String boundary = params.split(" ")[0]; //获得分割后的参数 String[] ps = Optional.ofNullable(params).orElse("").split(boundary); for (String p : ps) { if(p.equals("")) continue; if (p.equals("-- ")) continue; p = p.trim().replaceAll(" ", "&&"); String[] ds = p.split(";"); //获得参数名 String nameMeta = Arrays.asList(ds).stream() .filter(d -> d.trim().startsWith("name=")) .findAny() .orElse(""); String name = Optional.ofNullable(nameMeta.split(""")[1]).orElse(""); //获得参数值 String value = Optional.ofNullable(StringUtils.substringAfter(p,"&&&&")).orElse(""); map.put(name, value); } return map; } public static String formDateToJson(String param){ return JSON.toJSONString(toMap(param)); } }