在使用zuul进行鉴权的时候,我们希望从请求Request中获取输入流,解析里面的内容,奈何InputStream只能被读取一次。为啥呢?源码里是这样说的:
public int read(byte[] b,int off, int len)
Reads up to len bytes of data into an array of bytes from this input stream. Ifpos equals count, then -1 is returned to indicate end of file. Otherwise, the number k of bytes read is equal to the smaller of len and count-pos.If k is positive, then bytes buf[pos] through buf[pos+k-1] are copied into b[off] through b[off+k-1] in the manner performed by System.arraycopy. The value k is added into pos and k is returned.
大致的意思是:在InputStream读取的时候,会有一个pos指针,它指示每次读取之后下一次要读取的起始位置。在每次读取后会更新pos的值,当你下次再来读取的时候是从pos的位置开始的,而不是从头开始,所以第二次获取String中的值的时候是不全的,API中提供了一个解决办法:reset()。但我发现在inputStream和servlet中根本不起作用。提示 mark/reset not supported 。意思是只有重写过markSupported()方法的IO流才可以用。所以一般我们使用inputStream,最好在一次内处理完所有逻辑。
那么就没法在中途获取请求流中的数据么?当然有办法了,我可是PPZ,只需要重写Request缓存一下流中的数据就好了,实现代码如下:
|
|
上述方案解决了使用request.getInpuStream()方法读取流中的数据只能读取一次的问题,其实当我们在使用第三方接口时,如果请求头信息和我们的服务所需不一致,例如第三方接口中头部信息为:content-type=text/plain;charset=UTF-8
而我们需要的是:”application/json;charset=utf-8”时,我们也是可以通过重写对应的方法对请求的头部信息进行修改的,代码如下:
|
|
当我们在后端设置了头部信息后,如果不出意外,前端发送的请求将变为简单请求,这样,服务器的处理机制将简单很多。