需求场景:

  公司对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请求参数的更多相关文章

  1. struts2视频学习笔记 11-12(动态方法调用,接收请求参数)

    课时11 动态方法调用 如果Action中存在多个方法时,可以使用!+方法名调用指定方法.(不推荐使用) public String execute(){ setMsg("execute&q ...

  2. SpringBoot系列教程web篇之Get请求参数解析姿势汇总

    一般在开发web应用的时候,如果提供http接口,最常见的http请求方式为GET/POST,我们知道这两种请求方式的一个显著区别是GET请求的参数在url中,而post请求可以不在url中:那么一个 ...

  3. java 修改HttpServletRequest的参数或请求头

    场景:过滤器中获取参数Token并添加到请求头(用户认证兼容老系统) 请求头和请求参数是不能直接修改,也没有提供修改的方法,但是可以在过滤器和拦截器中使用HttpServletRequestWrapp ...

  4. Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题

    Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题 继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题.最近很多接口,收到 ...

  5. Http协议入门、响应与请求行、HttpServletRequest对象的使用、请求参数获取和编码问题

    1 课程回顾 web入门 1)web服务软件作用: 把本地资源共享给外部访问 2)tomcat服务器基本操作 : 启动:  %tomcat%/bin/startup.bat 关闭: %tomcat%/ ...

  6. 通过zuul修改请求参数——对请求参数进行解密

    zuul是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用,Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架,Zuul 相当于是设备和 ...

  7. HttpServletRequest修改/添加header和cookie参数

    实现功能: 所有接口经过过滤器,获取每个接口的自定义头部(token) 判断如果是app访问,则给头部设置cookie,值为自定义token的值. 即:使用过滤器实现修改请求头headers 实现步骤 ...

  8. 修改request请求参数

    本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除: 但在后台程序中,一般对request的参数的操作,都是通过request的getParameter.getParameter ...

  9. 使用HttpServletRequestWrapper修改请求参数 和 使用HttpServletResponseWrapper截获响应数据

    Servlet规范中的Filter引入了一个功能强大的拦截模式.Filter能在request到达servlet的服务方法之前拦截request对象,而在服务方法转移控制后又能拦截response对象 ...

随机推荐

  1. 初识C#扩展方法

    1)扩展方法是什么? 扩展方法可以在不修改原有类的代码前提下,给类“增加”一个方法.扩展方法虽然属于静态方法,但调用的语法却和对象调用类似.直接用一个例子来演示扩展方法. 1.准备实体类 public ...

  2. 华为云MVP熊保松谈物联网开发:华为云IoT是首选,小熊派是神器

    摘要:在AI.5G的技术驱动下,物联网行业的发展愈加如火如荼,开发者在技术的快速更迭间,也得乘风破浪跟上新技术的节奏. 在AI.5G的技术驱动下,物联网行业的发展愈加如火如荼,开发者在技术的快速更迭间 ...

  3. Pandas基础知识图谱

    所有内容整理自<利用Python进行数据分析>,使用MindMaster Pro 7.3制作,emmx格式,源文件已经上传Github,需要的同学转左上角自行下载或者右击保存图片.该图谱只 ...

  4. CSRF攻击原理以及防御方法(写的很好)

    转载地址:http://www.phpddt.com/reprint/csrf.html        CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟 ...

  5. Scala 面向对象(十):特质(接口) 三

    1 在特质中重写抽象方法特例 提出问题,看段代码 trait Operate5 { def insert(id : Int) } trait File5 extends Operate5 { def ...

  6. web 部署专题(一):Gunicorn运行与配置方法

    Gunicorn“绿色独角兽”是一个被广泛使用的高性能的Python WSGI UNIX HTTP服务器,移植自Ruby的独角兽(Unicorn )项目,使用pre-fork worker模式,具有使 ...

  7. 输入Javac提示不是内部或外部命令怎么办

    首先,我们在电脑上面找到此电脑, 然后右键点击,选择属性.   在属性中,我们找到高级系统设置,点击打开,如图示.   然后在系统设置中,我们可以找到启动和鼓掌恢复,然后点击环境变量,点击打开.   ...

  8. nodejs之数据库连接

    nodejs 对 MySQL.mongodb.redis 数据库的连接方式. MySQL: var mysql = require('mysql') var { MYSQL } = require(' ...

  9. scrapy shell 遇到的问题

    有时候用scrapy shell来调试很方便,但是有些网站有防爬虫机制,所以使用scrapy shell会返回403,比如下面 有两种解决方法: (1):第一种方法是在命令上加上-s USER_AGE ...

  10. 【一起学系列】之命令模式:封装一个简单Jedis

    意图 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 命令模式的诞生 [产品]:开发小哥,来活啦,咱们需要设计一款遥控器,核心功能就 ...