有一个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数据流再传递的更多相关文章

  1. java的值传递笔记

    1. 背景:开发小伙伴突然问我java是值传递还是引用传递,我说当然是值传递,只不过有时候传递一个对象时实际传递的是对象的地址值,所以让人容易产生一种引用传递的假象,貌似在李刚的疯狂java讲义有提到 ...

  2. java是值传递还是引用传递

    首先写一个简便的Employee,以便测试使用. class Employee { private String name; public Employee(String name) { this.n ...

  3. java參数传递机制浅析

    欢迎转载,转载请声明出处! ----------------------------------------- 前言: java语言中,參数的传递仅仅有一种机制.那就是值传递. 举例: 以下将通过几个 ...

  4. java面试3-对于java中值传递的理解(Hollis)

    这是根据Hollis的直面java内容习得(有兴趣的可以加他微信公众号) 对于初学者来说,要理解java中的值传递很难理解,为什么说java只有值传递?那引用传递呢? java中的错误理解: 错误理解 ...

  5. 堆栈详解 + 彻底理解Java的值传递和引用传递

    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...

  6. Java只有值传递(Java值传递还是引用传递?)

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10830521.html 一:区分Java数据类型.变量类型 Java数据类型分两种:基本数据类型.引用类型. ...

  7. Java的值传递和引用传递的说法

    学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java ...

  8. Java命令行传递参数

    目录 命令行传参 代码运行 视频 命令行传参 有时候你希望运行一个程序的时候再传递给它消息. 这要靠传递命令行参数给main()函数实现 package com.broky.base; public ...

  9. Java 为值传递而不是引用传递

    ——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...

随机推荐

  1. spring boot 登录注册 demo (四) -- 体验小结

    之前没有折腾过Spring,直接上来怼Spring Boot异常痛苦,参考着官网的guide(https://spring.io/guides)写了几个demo: spring boot 跑起来确是方 ...

  2. scope引起的问题

    背景 执行mvn clean test命令提示部分包不存在,但通过eclipse的clean操作后可以执行mvn test命令 解决方法 mvn clean操作为清空编译的class文件,test的话 ...

  3. Leetcode - Letter Combination Of A Phone Number

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  4. 区别jquery对象和dom对象及转换方法

    一.jquery对象 由$() 获取,例如 var div = $("#id"); 这个div是jquery对象,它里面没有dom对象自带的方法.常见的dom对象自带的方法, 例如 ...

  5. latex 生成pdf

    我个人还是比较推崇传统的方法:先生成dvi,在生成pdf. 直接在winEdt中点击最下方的Windows Command Prompt, 否则从cmd进入命令行的话,还要进入tex文件夹,好麻烦. ...

  6. super函数没有那么简单-super原理剖析

    开始之前,先出一道题: #super函数探讨 class A(object): def __init__(self): print 'A.__init__' class B(A): def __ini ...

  7. 【BUG】插入或者更新超过限制后写入数据库失败

      Error Code: 1064 - You have an error in your SQL syntax; check the manual that corresponds to your ...

  8. 常用的十大Python开发工具

    据权威机构统计,Python人才需求量每日高达5000+,但目前市场上会 Python 的程序员少之又少, 竞争小,很容易快速高薪就业.可能你并不太了解常用的十大Python开发工具都有哪些,现在告诉 ...

  9. JQuery操作iframe父页面与子页面的元素与方法

    JQuery操作iframe父页面与子页面的元素与方法 JQUERY IFRAME 下面简单使用Jquery来操作iframe的一些记录,这个使用纯JS也可以实现. 第一.在iframe中查找父页面元 ...

  10. DB Error || Warning

    数据库在进行增删改查时有时候会发生错误,当在程序中一个操作总是不起作用的时候,我们可以尝试如下方法: 1.输出sql语句,有的sql语句可能是通过一些字符拼接完成的,这时候可能会发生'', +之类的混 ...