springcloud zuulfilter 实现get,post请求日志记录功能
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("\r\n")[0];
//获得分割后的参数
String[] ps = Optional.ofNullable(params).orElse("").split(boundary);
for (String p : ps) {
if(p.equals(""))
continue;
if (p.equals("--\r\n"))
continue;
p = p.trim().replaceAll("\r\n", "&&");
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));
} }
springcloud zuulfilter 实现get,post请求日志记录功能的更多相关文章
- 如何从Serilog请求日志记录中排除健康检查终结点
这是在ASP.NET Core 3.X中使用Serilog.AspNetCore系列文章的第四篇文章:. 第1部分-使用Serilog RequestLogging减少日志详细程度 第2部分-使用Se ...
- HAproxy增加日志记录功能和自定义日志输出内容、格式
http://blog.51cto.com/eric1/1854574 一.增加haproxy日志记录功能 1.1 由于数据分析的需要,我们必须打开haproxy日志,记录相关信息. 在配置前,我 ...
- 如何自行给指定的SAP OData服务添加自定义日志记录功能
有的时候,SAP标准的OData实现或者相关的工具没有提供我们想记录的日志功能,此时可以利用SAP系统强大的扩展特性,进行自定义日志功能的二次开发. 以SAP CRM Fiori应用"My ...
- 在SpringBoot中用SpringAOP实现日志记录功能
背景: 我需要在一个SpringBoot的项目中的每个controller加入一个日志记录,记录关于请求的一些信息. 代码类似于: logger.info(request.getRequestUrl( ...
- 个人理解---在开发中何时加入日志记录功能[java]
是这样的:俩个月前做的一个小功能,今天经理突然问我这个'清除复投记录'功能是不是我做的,我说是,很久以前了.他说昨天一个客户找过来了,后台把人家的复投记录清除掉了,不知道何时清除的,我记得当时做的时候 ...
- iptables log日志记录功能扩展应用:iptables自动配置临时访问策略,任意公网登录服务器
一.修改日志记录: 1. 修改配置文件: vi /etc/rsyslog.conf 添加以下内容 #iptables log kern.=notice /var/log/iptables.log 2. ...
- tp5下通过composer实现日志记录功能
tp5实现日志记录 1.安装 psr/log composer require psr/log 它的作用就是提供一套接口,实现正常的日志功能! 我们可以来细细的分析一下,LoggerInterface ...
- spring Boot使用AOP统一处理Web请求日志记录
1.使用spring boot实现一个拦截器 1.引入依赖: <dependency> <groupId>org.springframework.boot</grou ...
- sqlmap批量扫描burpsuite请求日志记录
sqlmap可以批量扫描包含有request的日志文件,而request日志文件可以通过burpsuite来获取, 因此通过sqlmap结合burpsuite工具,可以更加高效的对应用程序是否存在SQ ...
随机推荐
- ACM学习历程—SNNUOJ1215 矩阵2(二分 && dfs)
http://219.244.176.199/JudgeOnline/problem.php?id=1215 这是这次微软和百度实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严 ...
- 加密第四节_IPSec基本理论
加密第四节_IPSec基本理论 本节内容 IPSec简介 IPSec两种工作模式 判断隧道模式和传输模式 IPSec两种模型 IPSec两个数据库 IPSec基本理论 IPSec简介 提供了网络层的安 ...
- Maven实现直接部署Web项目到Tomcat7
如题目,自动部署到Web服务器,直接上过程. 1.Tomcat7的用户及权限配置:在conf目录下,找到tomcat-users.xml,添加manager权限的用户. <role rolena ...
- Linux基础命令-echo
echo命令 功能:显示字符 (末尾自带换行功能) 语法:echo [-neE][字符串] 说明:echo会将输入的字符串送往标准输出.输出的字符串间以空白字符隔开, 并在最后加上换行号 -n 不在字 ...
- win32 获取本机网卡信息(MAC地址,IP地址等)
由于一个需求需要获取网卡的MAC地址,就搜了一下,大部分都是COPY来COPY去的一些代码,有很多甚至不能直接运行或有还有内存泄漏.自己查了一下MSDN然后封装了一下: 需要注意,一个机器可能有多个网 ...
- bash 中的行处理命令 awk
转自:http://blog.chinaunix.net/uid-23302288-id-3785105.html
- (转)配置ORACLE 11g绿色版客户端和PLSQL环境
本文转载自:http://my.oschina.net/jang/blog/83009 本方法是通过使用ORACLE官方提供的精简版客户端,即绿色免安装的客户端. 下载地址(此处提供的是官方各版本下载 ...
- 将Windows下磁盘出现黑色为分配区域变成绿色区域
在windows下不知什么原因, 有一块磁盘空间F盘就变成了黑色为分配区域. 黑色区域无法用来安装双系统, 网上查阅资料后, 找到了如何将他重新变回绿色区域的2个方法(方法二是自己无意操作成功的). ...
- 运动事件Motion Events
备注:运动事件,也是加速度时间,一般像摇晃手机就属于运动事件 监听运动事件对于UI控件有个前提就是监听对象必须是第一响应者(对于UIViewController视图控制器和UIAP ...
- HDU 4879 ZCC loves march (并查集,set,map)
题面以及思路:https://blog.csdn.net/glqac/article/details/38402101 代码: #include <bits/stdc++.h> #defi ...