• 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("
    ")[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));
        }
    
    }
  • 相关阅读:
    Spring(二) Spring装配Bean的几种方式
    Spring(一) Spring配置文件中classpath和classpath*的区别
    学习响应式编程 Reactor (5)
    学习响应式编程 Reactor (4)
    学习响应式编程 Reactor (3)
    学习响应式编程 Reactor (2)
    学习响应式编程 Reactor (1)
    学习Java 8 Stream Api (5)
    学习Java 8 Stream Api (4)
    Spring WebFlux 学习笔记
  • 原文地址:https://www.cnblogs.com/keepMoveForevery/p/9669543.html
Copyright © 2020-2023  润新知