直奔主题
实现方法:
SpringMVC是通过前端控制器(DispatcherServlet)接收请求进行请求转发的,所以可以从这里入手把request对象替换为自定义的request对象,从而解决request的输入流只能读取一次的问题.
步骤:
1..重写service方法,实现替换request操作
package org.XXX.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.XXX.request.CustomRequest;
public class DispatcherServlet extends org.springframework.web.servlet.DispatcherServlet {
private static final long serialVersionUID = 6781076086037842254L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 全局替换request对象
super.service(new CustomRequest(request), response);
}
}
将我们自己的前端控制器配置到web.xml中
<servlet>
<servlet-name>springmvc</servlet-name>
<!-- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> -->
<servlet-class>org.XXX.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
至此request替换操作已经完成,下面进入重点.
2.实现自己的HttpServletRequest
package org.XXX.request;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils;
/**
* 自定义Request
*
*/
public class CustomRequest extends HttpServletRequestWrapper {
private byte[] postBody;
public CustomRequest(HttpServletRequest request) {
super(request);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (postBody == null) {
postBody = IOUtils.toByteArray(super.getInputStream());
}
return new CustomServletInputStream(postBody);
}
/**
* 自定义ServletInputStream
*
*/
private static class CustomServletInputStream extends ServletInputStream {
private final InputStream is;
CustomServletInputStream(byte[] postBody) {
if (postBody == null) {
postBody = new byte[0];
}
this.is = new ByteArrayInputStream(postBody);
}
@Override
public int read() throws IOException {
return is.read();
}
}
}
大功告成!!
最后附上AOP方法中读取post内容的部分代码
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String requestBody = null;
if ("POST".equals(request.getMethod())) {
// 读取requestBody
byte[] bytes = IOUtils.toByteArray(request.getInputStream());
requestBody = new String(bytes,request.getCharacterEncoding());
}else{
Map<String,String[]> parameterMap = request.getParameterMap();
if(parameterMap != null && !parameterMap.isEmpty()){
requestBody = gson.toJson(parameterMap);
}
}
if (requestBody != null && !requestBody.isEmpty()) {
logger.info("requestBody: " + requestBody);
}
|