背景 通常对安全性有要求的接口都会对请求参数做一些签名验证,而我们一般会把验签的逻辑统一放到过滤器或拦截器里,这样就不用每个接口都去重复编写验签的逻辑. 在一个项目中会有很多的接口,而不同的接口可能接收不同类型的数据,例如表单数据和json数据,表单数据还好说,调用request的getParameterMap就能全部取出来.而json数据就有些麻烦了,因为json数据放在body中,我们需要通过request的输入流去读取. 但问题在于request的输入流只能读取一次不能重复读取,所以我们在…
1.需求:给某些请求接口记录日志,记录请求的数据和响应的数据和请求所花费的时间.这里采用非侵入式编程,也业务代码进行解耦.按照spring AOP 的编程思想. 2.编程设计:在spring 拦截器中植入日志代码.因为其刚好满足非侵入,且能捕获到请求和响应的数据. 3.了解spring 拦截器和过滤器的运行原理 先执行过滤器,然后执行拦截器. 4. 分析:当在拦截器中获取请求的输入流和响应的输出流的时候发现,只能读取一次,拦截器在具体的业务代码之前执行,导致请求的输入流被拦截器使用,到contr…
大家在开发过程中,可能会遇到对请求参数做下处理的场景,比如读取上送的参数中看调用方上送的系统编号是否是白名单里面的(更多的会用request中获取IP地址判断).需要对请求方上送的参数进行大小写转换或者字符处理.或者对请求方上送的用户名参数判断是否有对当前请求地址的访问权限(多用于越权处理)等,这些都可以通过实现Filter自定义一个类,在该类中进行相应处理.但是会有个问题,如果是POST请求过来,在Filter的实现类中读取了请求参数,那么后续在Controller里面就无法获取,这是由于我们…
业务逻辑,通过filter读取请求的request,获取token,并将token传递后面流程使用 BodyReaderHttpServletRequestWrapper: public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; public BodyReaderHttpServletRequestWrapper(HttpServ…
解决SpringMVC拦截器中Request数据只能读取一次的问题 开发项目中,经常会直接在request中取数据,如Json数据,也经常用到@RequestBody注解,也可以直接通过request.getParameter()从Request中取数据. 但是有时候我们要在请求到具体的业务之前做一些操作比如日志记录.数据校验.统一的处理等等,可以在拦截器中处理. 由于 request中getReader()和getInputStream()只能调用一次,我们在拦截器中获取Request中数据后…
首先,我们复习一下InputStream read方法的基础知识, java InputStream read方法内部有一个,postion,标志当前流读取到的位置,每读取一次,位置就会移动一次,如果读到最后,InputStream.read方法会返回-1,标志已经读取完了,如果想再次读取,可以调用inputstream.reset方法,position就会移动到上次调用mark的位置,mark默认是0,所以就能从头再读了. 当然,能否reset是有条件的,它取决于markSupported,m…
问题: 一次开发过程中同事在 sptring interceptor 中获取 request body 中值,以对数据的校验和预处理等操作 .导致之后spring 在读取request body 值做数据映射时一直报 request body is null .以此在这通过源码回顾了一下 InputStream read 的方法中的基础知 首先来看看inputStream 中 read() 源码 实现以 ByteArrayInputStream 中源码来查看: 1: inputStream re…
场景交代 在springboot中添加拦截器进行权限拦截时,需要获取请求参数进行验证.当参数在url后面时(queryString)获取参数进行验证之后程序正常运行.但是,当请求参数在请求体中的时候,通过流的方式将请求体取出参数进行验证之后,发现后续流程抛出错误: Required request body is missing ... 经过排查,发现ServletInputStream的流只能读取一次(参考:httpServletRequest中的流只能读取一次的原因). 这就是为什么在拦截器…
1. 我们先来看一下继承关系HttpServletRequest 接口继承ServletRequest接口 public abstract interface  ServletRequest{ public abstract ServletInputStream getInputStream()  throws IOException; } 从上面可知request.getInputStream()返回的是ServletInputSteam.查看ServletInputStream源码可知,Se…
转自:https://www.jianshu.com/p/85feeb30c1ed HttpServletRequest.getInputStream()多次读取问题   背景 使用POST方法发送数据时,我们习惯于把数据包装成json格式.   image.png 有些情况下,我们会在Filter中读取body数据进行数据校验,GET方法获取参数比较简单.对于POST方法,可使用如下方法从request中获取body参数: private String getBody(HttpServletR…