开发者社区> 问答> 正文

springmvc实现restful service时,怎么样用日志记录每次的请求参数:报错

大致需求是这样的,用springmvc去实现restful的service,由于跟客户端(web,android,ios)进行调试时,想要知道对方传递过来的参数是什么样子的,希望用日志记录下来。但有些疑问:


  1. 现在用是@RequstBody注解获取到了body里面的内容,但是如果用拦截器的方式,以request.getInputstrem()流的形式读取body内容后,在controller里会报Required request body is missing因为流一旦被读取就没有了
  2. 有什么方式可以记录每次客户端的请求body,并打印出来。queryString和params都好说,比较容易实现
  3. 大家的项目在用springmvc作restful service时有记录过客户端的请求参数时,用的什么方式

希望大家能共同探讨,不惜赐教。感谢

展开
收起
kun坤 2020-06-06 16:28:32 648 0
1 条回答
写回答
取消 提交回答
  • 使用 Spring 的 AOP,具体代码如下(仅做参考):
    
    @Component
    @Aspect
    public class AopLog {
       private static final Logger log = LoggerFactory.getLogger(AopLog.class);
        // 提示信息格式
        private final static String msg = "\r\nIP:{}\r\nURL:{}\r\nHTTP_METHOD:{}\r\nCLASS_METHOD:{}\r\nARGS:{}\r\nResult:{}\r\nConsuming:{}ms\r\n";
        
    
        @Pointcut("execution(public * com.hong..*Controller.*(..))")
        public void log() {
        }
    
        @Around("log()")
        public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
            long startTime = System.currentTimeMillis();        // 方法开始执行的时间
    
            String args = Arrays.toString(joinPoint.getArgs()); // 方法参数
            String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();    // 调用的方法
            Object result = null;
    
            /*
             * 获取 request 信息
             */
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String url = "", httpMethod = "", ip = "";
            if(attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                // 记录下请求内容
                url = request.getRequestURL().toString();
                httpMethod = request.getMethod();
                ip = getIpAddr(request);
            }
            
            long methodEnd;
            
            // 执行方法,如果有异常,则进行记录
            try {
                result = joinPoint.proceed();
            } catch (Exception e) {
                methodEnd = System.currentTimeMillis();     // 记录出现异常时的执行时间
                
                result = e.getMessage();
                
                log.error(msg, ip, url, httpMethod, classMethod, args, result, methodEnd - startTime, e);
                
                throw e;
            }
            
            methodEnd = System.currentTimeMillis();     // 记录方法正常执行后时间
            log.info(msg, ip, url, httpMethod, classMethod, args, result, methodEnd - startTime);
            
            return result;
        }
        
        /**
         * 获取客户端IP
         * @param request       HttpServletReqeust信息
         * @return              IP
         */
        private String getIpAddr(HttpServletRequest request) {
            String ip = request.getHeader("x-forwarded-for");
            
            if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            
            if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            
            if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            
            return ip;
        }
    }

     

    ######

    org.springframework.web.servlet.handler.HandlerInterceptorAdapter

    不知道有用不

    ######现在就是用这种方式处理的,但是如果在interceptor里面读取了流里面的body内容,到达controller的时候,就读不到body了,因为流里面的内容被读取过就没有了######

    aop

    aspectJ

    ######

    楼主解决了吗??求指点。

    2020-06-06 16:28:37
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
PostgresChina2018_赖思超_PostgreSQL10_hash索引的WAL日志修改版final 立即下载
Kubernetes下日志实时采集、存储与计算实践 立即下载
日志数据采集与分析对接 立即下载