java filter修改request内容和response内容

java filter修改request内容和response内容

背景

最近在做一个开放平台,因为是对外开放的api,所以针对api做了签名和加密机制

请求阶段:原始request body 加密 -> encrypt body -> 签名,放到header

响应阶段:原始response body 加密 -> encrypt body -> 签名,放到header

方案

对于这种通用的http请求处理,最容易想到的就是通过java servlet filter或者spring mvc interceptor来做,具体原理可以参见下图

对于spring mvc interceptor,可以看下接口定义

因为需要针对request做签名验证和解密操作,因此需要对request和response做修改,springmvc中,request body和response body都是基于流(stream)来做的,但是stream只能读取一次;因此我们需要对request和response做一些处理

事实上,springmvc interceptor并不适合此场景,具体可以参考HandlerInterceptor接口定义

此处修改request或者response并不会对后续的请求生效,因为HttpServletRequest,HttpServletResponse都未提供对流的修改操作

此时只能选择java servlet filter,我们看下filter接口定义

通常我们实现一个filter是流程如下

事实上,我们依然无法修改request和reposne的stream对象,但是chain.doFilter时,我们可以传递一个和原始request, response不一样的对象

那么此处的filter流程如下

1、从header读取签名

2、从request读取request body,解密

3、校验签名,签名不通过,直接返回错误

4、构造新的request,request body内容是request body解密后的内容

5、构造新的response

6、根据新的request, resepond,通过chain.doFilter()继续往下执行

7、读取response body部分,并加密

8、生成签名,放入header

9、通过原始reponse,写入response body加密后的内容

整体框架代码如下

具体的RequestWrapper,ResponseWrapper代码如下

最后更新于