@RequestBody注解的参数仅仅读取一次的问题解决。

最近在写日志管理,想着使用拦截器加注解的方式,但是遇到了一个问题,就是如果使用@RequestBody注解接收的参数只能读取一次,造成了我在拦截器中如果接收了参数,在Controller层就接收不到了,为了解决这个问题,在网上查了方法。自定义一个MyRequestWrapper 继承 HttpServletRequestWrapper不多说,看代码:

package cn.huimin100.cms.handler;
 
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
 
/**
* 与HttpServletRequestWrapperFilter配合使用,保证@RequestBody注解的参数可以读取两次
* 因为要在拦截器中获取参数
*/
public class MyRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
}
 
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
 
 
@Override
public boolean isFinished() {
return false;
}
 
@Override
public boolean isReady() {
return false;
}
 
@Override
public void setReadListener(ReadListener readListener) {
 
}
 
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
 
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
 
public String getBody() {
return this.body;
}
}
 
需要结合过滤器使用:
package cn.huimin100.cms.handler;
 
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
 
/**
* 该过滤器与MyRequestWrapper配合使用,可以让@RequestBody注解的参数至少可以读取两次,
* 从而使得在拦截器中可以获取@RequestBody注解的参数。
*/
@WebFilter(filterName="HttpServletRequestWrapperFilter",urlPatterns="/*")
public class HttpServletRequestWrapperFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
 
}
 
@Override
public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper= null;
if(request instanceof HttpServletRequest){
requestWrapper = new MyRequestWrapper((HttpServletRequest) request);
}
if(null == requestWrapper){
filterChain.doFilter(request,servletResponse);
}else{
filterChain.doFilter(requestWrapper,servletResponse);
}
}
 
@Override
public void destroy() {
 
}
}
 
拦截器中这样获取参数
package cn.huimin100.cms.handler ;
 
import cn.huimin100.cms.config. LogAnnotation ;
import cn.huimin100.cms.mapper.newcms.ActionLogsMapper ;
import cn.huimin100.cms.pojo.po.ActionLogs ;
import cn.huimin100.cms.util.DateUtil ;
import com.alibaba.fastjson.JSONObject ;
import org.apache.commons.lang.time.DateFormatUtils ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import org.springframework.beans.factory.annotation. Autowired ;
import org.springframework.web.method.HandlerMethod ;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter ;
 
import javax.servlet.http.HttpServletRequest ;
import javax.servlet.http.HttpServletResponse ;
import java.lang.reflect.Method ;
import java.util.Date ;
import java.util.Map ;
 
/**
* 在读取@RequestBody注解的参数的时候,需要配合MyRequestWrapper使用
* 一遍保证这些参数可以在Controller层再次读取
*/
public class LogManageInterceptor extends HandlerInterceptorAdapter {
private final Logger logger = LoggerFactory. getLogger (LogManageInterceptor. class ) ;
 
@Autowired
private ActionLogsMapper logMapper ;
 
public static final String USER_NAME = "user__name" ;
public static final String BRANCH_ID = "branch__id" ;
public static final String USER_ID = "user__id" ;
@Override
public boolean preHandle (HttpServletRequest request , HttpServletResponse response , Object handler) throws Exception {
 
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler ;
Method method = handlerMethod.getMethod() ;
LogAnnotation annotation = method.getAnnotation( LogAnnotation . class ) ;
if (annotation != null ){
try {
ActionLogs log = new ActionLogs() ;
//操作类型
log.setAction(annotation.action().getCode()) ;
//操作目标方法
log.setCategory(annotation.targetMethod().getCode()) ;
//操作人姓名
log.setActionTime(DateFormatUtils. format ( new Date() , DateUtil. DATETIME_DEFAULT_FORMAT )) ;
log.setIsmiddlemode( 2 ) ;
Map<String , String[]> parameterMap = request.getParameterMap() ;
if (parameterMap == null || parameterMap.isEmpty()){
MyRequestWrapper myRequestWrapper = new MyRequestWrapper((HttpServletRequest) request) ;
String body = myRequestWrapper.getBody() ;
JSONObject jsonObject = JSONObject. parseObject (body) ;
log.setOperator(jsonObject.getString( USER_NAME )) ;
log.setOperatorId(jsonObject.getInteger( USER_ID )) ;
log.setBranchId(jsonObject.getInteger( BRANCH_ID )) ;
} else {
log.setOperator(request.getParameter( USER_NAME )) ;
log.setOperatorId(Integer. valueOf (request.getParameter( USER_ID ))) ;
log.setBranchId(Integer. valueOf (request.getParameter( BRANCH_ID ))) ;
}
logMapper .insertSelective(log) ;
} catch (Exception e){
logger .error( "记录操作日志错误 e:{}" , e) ;
}
}
}
return true;
}
}

猜你喜欢

转载自www.cnblogs.com/bfyq/p/9265803.html