Spring Boot如何实现内部转发调用接口并保留cookie以减少客户端请求
结论:完全可以实现,不需要修改原有两个接口的业务逻辑,有两种成熟方案可选
方案1:Servlet内部转发(同服务实例场景首选,性能最高)
这个方案完全在当前请求的服务端上下文内执行,不需要发起额外的HTTP请求,和客户端两次调用的效果100%一致:
- 首先新增一个聚合接口,客户端仅需调用这一个接口即可完成原有两次请求的业务流程
- 聚合接口内先调用第一个原有接口的方法,传入当前请求的
HttpServletRequest和HttpServletResponse对象,第一个接口生成的Cookie会自动写入当前response的Cookie列表 - 调用
request.getRequestDispatcher("第二个接口的路径")的forward()方法,直接内部转发到第二个接口
内部转发共享同一个请求上下文,第二个接口读取Cookie、Session等上下文参数的逻辑完全不需要修改,读取到的内容和客户端主动发起两次请求拿到的完全一致
- 第二个接口的响应会直接通过聚合接口返回给客户端,你也可以根据业务需要先处理响应内容再返回
方案2:服务端模拟HTTP调用(跨服务实例场景适用)
如果两个接口部署在不同的服务实例,或者内部转发有其他限制,可以用Spring自带的HTTP客户端替客户端完成两次调用:
- 同样先新增聚合接口,客户端仅调用一次
- 聚合接口内先用
RestTemplate或者WebClient调用第一个接口,从响应头的Set-Cookie字段拿到第一个接口生成的所有Cookie - 把上一步拿到的Cookie填充到第二个请求的
Cookie请求头中,调用第二个接口 - 将第二个接口的响应内容返回给客户端,同时可以把需要持久化到客户端的Cookie写入最终的响应头
这种方式的开销仅为服务端内部的网络请求延迟,远低于客户端跨公网两次请求的往返开销,对原有接口的逻辑无任何侵入
关键注意点
- 如果第二个接口依赖Session存储的内容,方案1天然支持不需要额外处理,方案2需要把SessionId也放到Cookie中携带
- 如果原有接口有权限校验逻辑,确保聚合接口的请求上下文和原客户端调用的上下文一致,避免权限校验失败
内容的提问来源于stack exchange,提问作者Andreas Wederbrand
相关产品推荐
相关产品推荐

