动态修改HttpServletRequest的Post请求参数
需求场景:
公司对APP调用的后台接口有个公用格式如下,外层包含了一些设备、版本、签名信息,主要的业务参数是在body里,外层信息都是在网关解决,验证签名后,在转发body到后台服务。
{
"appVersion":"1.0.0",
"equipmentNo":"***********",
"equipmentType":"ios",
"mobile":"134*******",
"registrationId":"*******",
"sign":"**********",
"token":"*************",
"body":"{*****}"
}
目前开发一个新的APP后台,要先提供接口与移动端联调,网关开发延后,这时的服务端接口是不能直接拿到body的,也不方便在@RequestBody参数都包装上外层的字段。
解决方法1:使用拦截器从HttpServletRequest获取POST数据,取出body数据,再替换HttpServletRequest的参数。
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
StringBuffer jb = new StringBuffer();
String line = null;
BufferedReader reader = null;
PrintWriter out = null;
try {
reader = request.getReader();
while ((line = reader.readLine()) != null){
jb.append(line);
}
JSONObject object = JSON.parseObject(jb.toString());
String body = object.getString("body");
out = response.getWriter();
out.append(body);
} catch (Exception e) {
e.printStackTrace();
if(reader != null){
reader.close();
}
if(out != null){
out.close();
}
}
}
这种方式可以提取POST传入的对象,并替换,但会报以下错误,所以还不建议使用。
getReader() has already been called for this request
解决方案二:使用AOP,拦截所有Controller
@Around(value = "allController()")
private void doAround(ProceedingJoinPoint joinPoint) {
try {
//所有参数
Object[] args = joinPoint.getArgs();
if(args != null && args.length > 0 ){
Object obj = args[0];
//记录@RequestBody注解的对象类型
Class<?> aClass = obj.getClass();
JSONObject object = JSON.parseObject(JSONUtil.toJson(obj));
//提取body,
String body = object.getString("body");
if(StringUtils.isNotBlank(body)){
//替换参数,并回写
body = body.replaceAll("\\\\","");
JSONObject bodyStr = JSON.parseObject(body);
args[0] = JSONUtil.fromJson(bodyStr.toJSONString(), aClass);
joinPoint.proceed(args);
}
}
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
这个方式顺利解决当前的问题,不过因为使用AOP,Spring框架已经对接收到的参数进行了转换,是拿不到body的值的。所以在所有Controller接口的请求参数类,都加一个String body 属性,才能接收到body的值。我是定义了一个公共对象,只有一个String body属性,让参数类集成这个公共对象,以后不用再删除就好了。
动态修改HttpServletRequest的Post请求参数的更多相关文章
- struts2视频学习笔记 11-12(动态方法调用,接收请求参数)
课时11 动态方法调用 如果Action中存在多个方法时,可以使用!+方法名调用指定方法.(不推荐使用) public String execute(){ setMsg("execute&q ...
- SpringBoot系列教程web篇之Get请求参数解析姿势汇总
一般在开发web应用的时候,如果提供http接口,最常见的http请求方式为GET/POST,我们知道这两种请求方式的一个显著区别是GET请求的参数在url中,而post请求可以不在url中:那么一个 ...
- java 修改HttpServletRequest的参数或请求头
场景:过滤器中获取参数Token并添加到请求头(用户认证兼容老系统) 请求头和请求参数是不能直接修改,也没有提供修改的方法,但是可以在过滤器和拦截器中使用HttpServletRequestWrapp ...
- Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题
Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题 继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题.最近很多接口,收到 ...
- Http协议入门、响应与请求行、HttpServletRequest对象的使用、请求参数获取和编码问题
1 课程回顾 web入门 1)web服务软件作用: 把本地资源共享给外部访问 2)tomcat服务器基本操作 : 启动: %tomcat%/bin/startup.bat 关闭: %tomcat%/ ...
- 通过zuul修改请求参数——对请求参数进行解密
zuul是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用,Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架,Zuul 相当于是设备和 ...
- HttpServletRequest修改/添加header和cookie参数
实现功能: 所有接口经过过滤器,获取每个接口的自定义头部(token) 判断如果是app访问,则给头部设置cookie,值为自定义token的值. 即:使用过滤器实现修改请求头headers 实现步骤 ...
- 修改request请求参数
本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除: 但在后台程序中,一般对request的参数的操作,都是通过request的getParameter.getParameter ...
- 使用HttpServletRequestWrapper修改请求参数 和 使用HttpServletResponseWrapper截获响应数据
Servlet规范中的Filter引入了一个功能强大的拦截模式.Filter能在request到达servlet的服务方法之前拦截request对象,而在服务方法转移控制后又能拦截response对象 ...
随机推荐
- 测试必备工具之抓包神器 Charles 如何抓取 https 数据包?
之前发过一篇文章讲解了Charles抓包工具的基本使用(有需要的小伙伴可以去看上一篇文章), 讲的数据包主要是http协议,大家可以看到数据包并直接显示具体详细的内容: 但是如果抓到的是https的 ...
- Rsync服务常见问题及解决
1. rsync服务端开启的iptables防火墙/selinux没关 [客户端的错误] No route to host [错误演示过程] [root@nfs01 tmp]# rsync -avz ...
- css 浮动 定位
浮动 元素的浮动是指设置了浮动属性的元素会脱离标准普通 流的控制,移动到其父元素中指定位置的过程. 语法: float . left . right . none(默认) 注意: 1 ...
- bzoj3791作业*
bzoj3791作业 题意: 对一个01序列进行染色,每次能将一个区间染上色(可覆盖之前染的),共能染k次,求最大正确染色个数.n≤100000,m≤50. 题解: 结论:染k次最多能把序列分成2*k ...
- Azure Web App (三)切换你的Net Core Web 项目的数据库连接字符串
一,引言 上一篇文章讲到今天我们演示了一下,如何在Web App中创建 “Deployment Slot”进行快速无停机部署新功能代码,也使用VS进行发布到创建的Web App中创建的新的部署槽位中, ...
- mysql间隙锁
什么是间隙锁(gap lock)? 间隙锁是一个在索引记录之间的间隙上的锁. 间隙锁的作用? 保证某个间隙内的数据在锁定情况下不会发生任何变化.比如我mysql默认隔离级别下的可重复读(RR). 当使 ...
- db2创建nickname
db2创建nickname创建步骤 1.创建 server create server servername type DB2/AIX version 10.5 wrapper drda authid ...
- vector基本用法
Vector作为STL容器中的一员,使用频率非常高,因此对其基本用法和实用技巧进行记录,便于后期查询使用. 基本用法 #include <iostream> #include <ve ...
- 题解 洛谷 P5443 【[APIO2019]桥梁】
考虑若只有查询操作,那么就可以构造\(Kruskal\)重构树,然后在线询问了,也可以更简单的把询问离线,把询问和边都按权值从大到小排序,然后双指针依次加入对于当前询问合法的边,用并查集维护每个点的答 ...
- python3的字符串常用方法
find()# 方法 find()# 范围查找子串,返回索引值,找不到返回-1 # 语法 s.find(substring, start=0, end=len(string)) # 参数 # subs ...