@Valid @Validated 参数校验出错时 如何查看 PSOT 请求的参数

最近在改造一个老项目的时候遇到了一个问题

1.项目中使用了@Validated注解 对接口入参进行校验
2.项目中有全局异常处理, 能捕获参数校验的异常, 但看不到POST请求的入参

这里就有些问题了

1.既然已经知道 某个字段传参有问题, 是否还需要打印参数? 
            其实也是看场景, 比如接口对接, 报错查问题还是很有价值的
2.增加了参数打印的逻辑会不会影响性能?
            多数项目并不会有很大的并发, 而且完全可以针对环境, 接口, 业务做区分(比如: 开发环境方便联调就打印参数, 线上稳定了就关闭)
3.是否每一个接口都需要打印入参? 
            可以在 全局异常处理时 打印入参; 换句话说就是 有异常报错的时后才打印

 ok, 在确定了 要做打印请求参数这件事后, 就需要确定用什么方案来做了

参考简单测试的结果:    Filter, Interceptor, Validator, Aop 执行顺序 Filter, Interceptor, Validator, Aop 执行顺序_zx1323的博客-CSDN博客

基本上可知, 用filter是一个不错的选择

Filter在读取POST请求时, 不像GET请求 使用 getParameterMap()来获取入参, POST请求中的body参数是以流形式存在的  

在尽量 使用spring原生类的 前提下, 有了如下尝试(原理都是一样的)
方式一  新写一个过滤器 继承AbstractRequestLoggingFilter: 【小家Spring】从OncePerRequestFilter的源码解读去了解Spring内置的Filter的特别之处以及常见过滤器使用介绍_YourBatman的博客-CSDN博客
        优点: 少量代码即可打印参数, 不受到验证框架影响; 参考上面链接中大佬的现成代码, GET POST请求等参数打印全都搞定
        缺点: 没有response的实现, 默认只有GET方法;


方式二 新写一个过滤器, 搭配ContentCachingRequestWrapper

        RequestWrapper requestWrapper = new RequestWrapper(request);// 执行doFilter方法前, 把HttpServletRequest包一下, 再传递下去
        filterChain.doFilter(requestWrapper, servletResponse);//执行


        取值不能用getInputStream(), 应该参考AbstractRequestLoggingFilter类的getMessagePayload(HttpServletRequest request)方法,
        如: new String(requestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8));
        在这个filter之前不能有别的filter调用过getInputStream()方法; 
        优点: spring已经实现了对 body数据流的拷贝
        缺点: 并不支持打印所有参数, 查看isFormPost()方法可知, 只支持POST请求和内容类型应为application/x-www-form-urlencoded, get请求的需要自行实现


方式三 基于方式二的自定义一个Wrapper类, 该方式灵活度更高, 比如能在执行doFilter方法前打印参数

最后, POST请求的流已经复制, 那么完全可以在 全局异常处理的时候再打印入参了
System.out.println(requestWrapper.getBodyString()); // 自定义的RequestWrapper类, 打印入参

可以参考: https://www.zhangshengrong.com/p/Mr1WJwwZXG/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值