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 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...
随机推荐
- Andrew Ng机器学习课程笔记--week4(神经网络)
Neural Networks: Representation 一. 内容概要 Neural Network Model Representation 1 Model Representation 2 ...
- 正则表达式-linux基础
通配符 通赔符是模糊匹配的基础,因为通赔符机制的存在使得我们在查找文件的时候非常方便 * :匹配任意长度的任意字符,也可以一个都没有 . :匹配任意单个字符,必须有一个 [ ] ...
- python基础教程(七)
本章介绍如何将语句组织成函数,这样,可以告诉计算机如何做事. 下面编写一小段代码计算婓波那契数列(前两个数的和是第三个数) fibs = [0,1] # 定义一个列表,初始内容是0,1 for i ...
- python 关于列表的增删改查及个别的命令
names = ["a","b","c","d","e","e","a ...
- python学习总结(面向对象进阶)
-------------------类属性和实例属性关系------------------- 1.类属性和实例属性关系 1.实例属性 实例对象独有的属性 2.类属性 ...
- Mysql only_full_group_by以及其他关于sql_mode原因报错详细解决方案
Mysql only_full_group_by以及其他关于sql_mode原因报错详细解决方案 网上太多相关资料,但是抄袭严重,有的讲的也是之言片语的,根本不连贯(可能知道的人确实不想多说) 我总共 ...
- 读redux有感: redux原来是这样操作的。
2017.9.10日 教师节 : ~当一个事物你没有接触,但是生活中 常常用到他,你就不得不去了解他了. 注:新手可以看一下,毕竟博主也是个菜鸟,没法写高深的东西,不想看博主扯淡的直接看第三节啦~~ ...
- Angular 新手容易碰到的坑
Q1.<div ng-include="views/user/show.html"></div> 错在哪里? 如果你这么写过,会发现这个位置啥也没有加载出来 ...
- jQuery EasyUI弹出确认对话框(确认操作中.....)
因为毕业设计的原因,在初期设计系统的时候没有考虑功能的正确性,所以很多的功能都没有加验证和确认的操作,给人在操作方面上有一些不好的感觉(可能失误点击后,数据就别删除,或者增加了),所以在网上找了一些资 ...
- js中面向对象的写法
function Circle(r){ this.r = r; }//构造(实例对象的)函数[思路二:这是一个类] Circle.PI = 3.14159; //属性 Circle.prototype ...