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();
}
}
上一篇:[CAMCOCO][C#]我的系统架构 总图


下一篇:phpstorm开启xdebug断点调试,断点调试不成功来这里