码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 一文带你了解如何使用spring拦截器获取请求体和响应体的内容


    ✨这里是小松猿的博客✨小松,欢迎您的到来~✨

    🍅系列专栏:无🍅

    ✈️本篇内容: spring拦截器获取请求体和响应体的内容

    🍱本篇收录完整代码地址:无🍱

    楔子

    一文带你了解如何使用spring拦截器获取请求体和响应体的内容

    springboot 日志记录接口的请求参数和响应结果的两种方式-拦截器和切面(具体代码)
    前言:在生产中如果出现问题,我们想要查看日志,某个时间段用户调用接口的请求参数和响应的返回结果,通过日志来推测下用户当时做了什么操作。日志记录接口的请求参数和响应结果有利于我们排查生产的问题,但是也会给系统带来内存性能的问题。所以我们需要权衡其中的利弊来选择,下面就是记录日志两种方式的具体代码。
     

    一、使用拦截器

    本来以为这种方式只要自定义拦截器继承HandlerInterceptorAdapter类重写preHandle() 和 afterCompletion()就可以了。没想到还是遇到挺多坑。

    请求参数:request.getParameterMap()可以获取到请求参数,但是如果接口是使用@RequestBody,就会发现得不到值。

    响应结果:这是比较蛋疼一点,我几乎查了response的所有方法,都发现没法得到接口响应结果。

    实现ResponseBodyAdvice类获取响应体的内容,需要在项目中引入jackson

    maven坐标:

    1. com.fasterxml.jackson.core
    2. jackson-databind
    3. 2.12.3

    代码如下,result就是对应接口响应的结果转换成了json格式存放在了result字符串中,然后将result存放在了httpSession中,用于拦截器处进行获取:

    1. @ControllerAdvice
    2. public class InterceptResponse implements ResponseBodyAdvice {
    3. private static final Integer MAX_LENGTH = 1000;
    4. @Override
    5. public boolean supports(MethodParameter methodParameter, Class> aClass) {
    6. return true;
    7. }
    8. @Override
    9. public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
    10. String result;
    11. ObjectMapper objectMapper = new ObjectMapper();
    12. try {
    13. result = objectMapper.writeValueAsString(body);
    14. } catch (JsonProcessingException e) {
    15. throw new RuntimeException("JSON转换失败", e);
    16. }
    17. Integer length = result.length();
    18. result = result.substring(0, length);
    19. HttpServletRequest httpServletRequest = ((ServletRequestAttributes)
    20. RequestContextHolder.getRequestAttributes()).getRequest();
    21. HttpSession httpSession = httpServletRequest.getSession(true);
    22. //放到缓存里,以便于可以在HandlerInterceptor拦截里取出并打印出返回结果
    23. httpSession.setAttribute("body", result)
    24. return body;
    25. }
    26. }
    27. 定义拦截器继承HandlerInterceptorAdapter

      1. @Component
      2. @Slf4j
      3. public class LogMonitorInterceptor extends HandlerInterceptorAdapter {
      4. @Override
      5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      6. String requestParams = StringUtils.EMPTY;
      7. if (request instanceof RequestWrapper) {
      8. requestParams = ((RequestWrapper) request).getBody();
      9. }
      10. if(StrUtil.isEmpty(requestParams)){
      11. requestParams = JSON.toJSONString(request.getParameterMap());
      12. }
      13. log.info("request: uri:{} , type:{} , ip:{}, operatorId:{}, operatorName:{}, params:{}",
      14. request.getRequestURI(),request.getMethod(),request.getRemoteAddr(),
      15. WebUtils.getId(),WebUtils.getUsername(), requestParams );
      16. return true;
      17. }
      18. @Override
      19. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      20. HttpSession httpSession = request.getSession();
      21. String result = (String) httpSession.getAttribute("body");
      22. log.info("response: url:{} , type:{} , ip:{}, operatorId:{}, operatorName:{}, result:{}",
      23. request.getRequestURI(),request.getMethod(),request.getRemoteAddr(),
      24. WebUtils.getId(),WebUtils.getUsername(), result );
      25. }
      26. }

      将拦截器注册在spring中:

      1. @Configuration
      2. public class WebMvcConfig implements WebMvcConfigurer {
      3. @Autowired
      4. private LogMonitorInterceptor logMonitorInterceptor;
      5. @Override
      6. public void addInterceptors(InterceptorRegistry registry) {
      7. // 接口操作日志拦截器
      8. registry.addInterceptor(logMonitorInterceptor);
      9. }
      10. }

       

    28. 相关阅读:
      STM32基础--初识 STM32
      【linux】补充:高效处理文本的命令学习(tr、uniq、sort、cut)
      centos同步服务器时间
      SpringBoot与Loki的那些事
      STM32F334高级定时器时钟选择
      k-均值聚类
      关于我一份阿里内部“Java面试核心笔记”,秋招拿下大厂offer这件事
      游戏模拟——Position based dynamics
      NAVICAT 15-自动运行-自动导出EXCEL 并自动发送邮件
      ESP32 入门笔记06: WIFI时钟 + FreeRTOS+《两只老虎》 (ESP32 for Arduino IDE)
    29. 原文地址:https://blog.csdn.net/qq_41625866/article/details/133807934
      • 最新文章
      • 攻防演习之三天拿下官网站群
        数据安全治理学习——前期安全规划和安全管理体系建设
        企业安全 | 企业内一次钓鱼演练准备过程
        内网渗透测试 | Kerberos协议及其部分攻击手法
        0day的产生 | 不懂代码的"代码审计"
        安装scrcpy-client模块av模块异常,环境问题解决方案
        leetcode hot100【LeetCode 279. 完全平方数】java实现
        OpenWrt下安装Mosquitto
        AnatoMask论文汇总
        【AI日记】24.11.01 LangChain、openai api和github copilot
      • 热门文章
      • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
        奉劝各位学弟学妹们,该打造你的技术影响力了!
        五年了,我在 CSDN 的两个一百万。
        Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
        面试官都震惊,你这网络基础可以啊!
        你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
        心情不好的时候,用 Python 画棵樱花树送给自己吧
        通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
        13 万字 C 语言从入门到精通保姆级教程2021 年版
        10行代码集2000张美女图,Python爬虫120例,再上征途
      Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
      正则表达式工具 cron表达式工具 密码生成工具

      京公网安备 11010502049817号