JAVA数据流再传递
有一个filter类,在请求进入的时候读取了URL信息,并且读取了requestBod中的参数信息,那么在请求到达实际的控制层时,入参信息是拿不到的,对这种情况就需要数据流做再传递处理。
处理原理:使用HttpServletRequestWrapper装饰类,重新定义获取流数据的方式。
自定义filter的实现:
package com.quyiyuan.openplatform.filter; import java.io.IOException;
import java.util.UUID; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import org.springframework.web.context.WebApplicationContext; import com.quyiyuan.openplatform.service.MonitorService; /**
* <pre>
* 任务:
* 描述:(存储用户请求信息,过滤器类)
* 作者:
* 时间:2015年11月5日下午12:03:33
* 类名: SaveRequestInfoFilter
* </pre>
*/
public class SaveRequestInfoFilter implements Filter{ private ServletContext servletContext; @Override
public void destroy() { } @Override
public void doFilter(ServletRequest sreq, ServletResponse srsp,
FilterChain fc) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) sreq;
String method = request.getMethod();
StringBuffer URL = request.getRequestURL();
if(URL.toString().contains("ROPcloudtest.html") || URL.toString().contains("ROPtest.html")
|| URL.toString().contains("ROP/css") || URL.toString().contains("ROP/js")
|| URL.toString().contains("YYSK.html")){
fc.doFilter(sreq, srsp);
}else{
String URI = "";
String urlParame = "";
String jsonParame = "";
String token = request.getParameter("token");
String userSource = request.getParameter("userSource");
String publicServiceType = request.getParameter("publicServiceType");
//request 作用域中添加UUID,标记当前请求
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
request.setAttribute("UUID", uuid); if (method.equals("POST")) {
URI = request.getRequestURI();
urlParame = request.getQueryString();
// 获取自定义装饰类对象
BodyReaderHttpServletRequestWrapper bodyWrapper = new BodyReaderHttpServletRequestWrapper(request);
jsonParame = HttpHelper.getBodyString(bodyWrapper);
saveReqInfo(URI, urlParame, jsonParame, token, userSource, publicServiceType, uuid);
// 使用自定义装饰类对象执行下一个过滤器
fc.doFilter(bodyWrapper, srsp);
} else {
URI = request.getRequestURI();
urlParame = request.getQueryString();
saveReqInfo(URI, urlParame, jsonParame, token, userSource, publicServiceType, uuid);
fc.doFilter(request, srsp);
}
}
} @Override
public void init(FilterConfig config) throws ServletException {
servletContext =config.getServletContext();
} /**
* <pre>
* 任务:
* 描述: 调用业务类保存请求信息
* 作者:
* 时间:2015年11月5日下午12:04:09
* @param URI
* @param urlParame
* @param jsonParame
* returnType:void
* </pre>
* @param publicServiceType
* @param userSource
* @param token
* @param uuid
*/
private void saveReqInfo(final String URI, final String urlParame, final String jsonParame, final String token,
final String userSource, final String publicServiceType, final String uuid) {
Thread saveReqInfo = new Thread() {
public void run() {
//获取容器对象
WebApplicationContext context = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//获取MonitorService对象
MonitorService monitorService = (MonitorService) context.getBean("monitorService");
monitorService.saveRequestInfo(URI, urlParame, jsonParame, token, userSource, publicServiceType, uuid);
}
};
saveReqInfo.start();
}
}
自定义装饰类的实现BodyReaderHttpServletRequestWrapper:
package com.quyiyuan.openplatform.filter; import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; import net.sf.json.JSONObject; import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset; /**
*
* <pre>
* 任务:
* 描述:(实现IO流再传递)
* 作者:
* 时间:2015年11月5日下午5:34:04
* 类名: BodyReaderHttpServletRequestWrapper
* </pre>
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));
} @Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
} @Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() { @Override
public int read() throws IOException {
return bais.read();
}
};
}
}
读取ServletRequest的body信息工具类:
package com.quyiyuan.openplatform.filter; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset; import javax.servlet.ServletRequest; /**
*
* <pre>
* 任务:
* 描述:(读取ServletRequest的body信息)
* 作者:
* 时间:2015年11月5日下午5:34:58
* 类名: HttpHelper
* </pre>
*/
public class HttpHelper {
public static String getBodyString(ServletRequest request) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
JAVA数据流再传递的更多相关文章
- java的值传递笔记
1. 背景:开发小伙伴突然问我java是值传递还是引用传递,我说当然是值传递,只不过有时候传递一个对象时实际传递的是对象的地址值,所以让人容易产生一种引用传递的假象,貌似在李刚的疯狂java讲义有提到 ...
- java是值传递还是引用传递
首先写一个简便的Employee,以便测试使用. class Employee { private String name; public Employee(String name) { this.n ...
- java參数传递机制浅析
欢迎转载,转载请声明出处! ----------------------------------------- 前言: java语言中,參数的传递仅仅有一种机制.那就是值传递. 举例: 以下将通过几个 ...
- java面试3-对于java中值传递的理解(Hollis)
这是根据Hollis的直面java内容习得(有兴趣的可以加他微信公众号) 对于初学者来说,要理解java中的值传递很难理解,为什么说java只有值传递?那引用传递呢? java中的错误理解: 错误理解 ...
- 堆栈详解 + 彻底理解Java的值传递和引用传递
本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...
- Java只有值传递(Java值传递还是引用传递?)
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10830521.html 一:区分Java数据类型.变量类型 Java数据类型分两种:基本数据类型.引用类型. ...
- Java的值传递和引用传递的说法
学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java ...
- Java命令行传递参数
目录 命令行传参 代码运行 视频 命令行传参 有时候你希望运行一个程序的时候再传递给它消息. 这要靠传递命令行参数给main()函数实现 package com.broky.base; public ...
- Java 为值传递而不是引用传递
——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...
随机推荐
- Linux 命令大全之Red Hat 7常用命令总结二
Linux 命令大全之RedHat7常用命令笔记... ----------------------------------------------------- 征服Linux从终端开始 ----- ...
- SSH2项目网上书店系统手把手教学_Struts2+Spring+Hibernate整合开发
一 序言 鉴于目前J2EE的火热程度,SSH2是每个学生毕业前都必须掌握的一门技术,所以在这里我就使用SSH2技术做一个小型项目,和大家一起学习. SSH2技术的基础概论就不再提了,直接说特点吧. 1 ...
- vue 父子组件传参
父向子组件传参 例子:App.vue为父,引入componetA组件之后,则可以在template中使用标签(注意驼峰写法要改成componet-a写法,因为html对大小写不敏感,component ...
- Docker 入门实践
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:张戈 导语 本文从新手视角记录了一个实际的Dokcer应用场景从创建.上传直到部署的详细过程,并简单的介绍了腾讯云容器服务的使用方法 ...
- java并发之原子性
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp17 1.原子性操作: 不能被线程调度机制中断的操作:--对原子性变量的赋值 ...
- 查看linux网卡硬件名称
查看linux网卡硬件名称 lspci | grep -i ether
- React——组件
一.创建组件 在React中有两种创建组件的方式,分别是函数形式的组件和类形式的组件 //函数形式: function Welcome(props){ return <p>this is ...
- 历上最强的音乐播放器(jetA…
原文地址:历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉化版)下载作者:盖世天星 历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉 ...
- 吐槽下微软的vs code编辑器
缺点:不能同时打开多个文件夹(打开多个文件夹得先ctrl+shift+N窗口或者除非你的所有项目文件都在同一个文件夹目录下) 优点是支持用户设置以及提供很多插件 // 将设置放入此文件中以覆盖默认设置 ...
- 软件工程(GZSD2015)第二次作业成绩
作业评分表 姓名 提交 语言 界面 PSP(3) CODE(4) 代码规范(2) 改进(1) 基本得分 提交时间 原始总得分 相对得分 最终得分 涂江凤 20150407 C CLI 3 4 2 1 ...