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 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...
随机推荐
- yii2 无法显示debug条的问题解决方法
显示debug条需要设置三个地方 一.web/index.php defined('YII_ENV') or define('YII_ENV', 'dev');//设置为开发者模式 二.config/ ...
- CSS三种样式表
1.外部样式表当样式需要应用于很多页面时,外部样式表将是理想的选择.在使用外部样式表的情况下,你可以通过改变一个文件来改变整个站点的外观.每个页面使用 <link> 标签链接到样式表. & ...
- SpringMVC的@RequestParam的解释
自SpringMVC4.2之后,RequestParam内部有4个参数: 1.String name 2.String value 3.boolean required 4.String defaul ...
- # hadoop入门第六篇:Hive实例
前言 前面已经讲了如何部署在hadoop集群上部署hive,现在我们就做一个很小的实例去熟悉HIVE QL.使用的数据是视频播放数据包括视频编码,播放设备编码,用户账号编码等,我们在这个数据基础上 ...
- shell 之解释器、变量、字符串、数组
1.Shell简介 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言.Shell 是指一种应用程序,这个应用程序提供了一个 ...
- web站点优化之使用tengine搭建静态资源服务器,静态资源合并加载案例剖析
在一个项目还是单体架构的时候,所有的js,css,image都会在一个web网站上,看起来并没有什么问题,比如下面这样: 但是当web网站流量起来的时候,这个单体架构必须要进行横向扩展,而在原来的架构 ...
- Javaweb项目碰到的问题- Access denied for user 'root'@'localhost' (using password: YES)
出现未给localhost root用户授权,主要是项目中存在的多个xxx.properties,其中用户名为root的password的值不完全相同导致的,使用eclipse的search 功能找到 ...
- 关于request和response的中文乱码问题
相信大家在开发Web项目中都会遇到中文的请求乱码和响应乱码的情况,现在给大家梳理一下并提供解决方案. 1.为什么会出现乱码: 出现乱码的根本原因是浏览器和服务器的解码方式不一致引起的.所以我们统一编码 ...
- Maven maven-compiler-plugin版本
项目执行Maven clean后出现WARNING提示.报如信息如下,根据报错信息 'build.plugins.plugin.version' for org.apache.maven.plugin ...
- Windows下Docker承载ASP.NET Core 应用
基本配置: Win7 64系统,Docker Toolbox, 主要步骤: [1]发布ASP.NET Core MVC应用,CD到项目根目录,执行dontnet publish [2]新建一个Dock ...