Request中getReader()和getInputStream()只能调用一次,构建可重复读取inputStream的request
- 添加RepeatedlyReadRequestWrapper 类并继承 HttpServletRequestWrapper 包装类
package net.dotclouds.requestconfig;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
public class RepeatedlyReadRequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
public RepeatedlyReadRequestWrapper(HttpServletRequest request)
throws IOException {
super(request);
body = readBytes(request.getReader(), "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 boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
private byte[] readBytes(BufferedReader br, String encoding) throws IOException{
String str = null,retStr="";
while ((str = br.readLine()) != null) {
retStr += str;
}
if (StringUtils.isNotBlank(retStr)) {
return retStr.getBytes(Charset.forName(encoding));
}
return null;
}
}
- 添加 RepeatedlyReadFilter 实现 filter 过滤器接口方法,当客户端的请求先 过滤 进入SpringMvc Dispatch 路由前先包装下
package net.dotclouds.filter;
import net.dotclouds.requestconfig.RepeatedlyReadRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class RepeatedlyReadFilter implements Filter {
private Logger log = LoggerFactory.getLogger(getClass());
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.debug("========复制request.getInputStream流=======");
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest) {
requestWrapper = new RepeatedlyReadRequestWrapper((HttpServletRequest) request);
}
if (null == requestWrapper) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
public void destroy() {
}
}
- 配置过滤器与拦截器 WebMvcConfig
package net.dotclouds.interceptor;
import net.dotclouds.filter.RepeatedlyReadFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
@EnableWebMvc
@ComponentScan
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
static final private String FAVICON_URL = "/favicon.ico";
static final private String PROPERTY_APP_ENV = "application.environment";
static final private String PROPERTY_DEFAULT_ENV = "dev";
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/").addResourceLocations("/**");
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
MyInterceptor myInterceptor = new MyInterceptor();
registry.addInterceptor(myInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
@Bean
public FilterRegistrationBean repeatedlyReadFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
RepeatedlyReadFilter repeatedlyReadFilter = new RepeatedlyReadFilter();
registration.setFilter(repeatedlyReadFilter);
registration.addUrlPatterns("/*");
registration.setOrder(1);
return registration;
}
}
- 添加拦截器 MyInterceptor 继承 HandlerInterceptorAdapter 拦截适配器
package net.dotclouds.interceptor;
import com.alibaba.fastjson.JSON;
import net.dotclouds.common.CloudBasisEnum;
import net.dotclouds.model.ResultStatus;
import net.dotclouds.requestconfig.RepeatedlyReadRequestWrapper;
import net.dotclouds.util.EncryptionUtil;
import net.dotclouds.util.MapUtil;
import net.dotclouds.util.ResultHelperUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import net.dotclouds.common.Constants;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Map;
public class MyInterceptor implements HandlerInterceptor{
private Logger log = LoggerFactory.getLogger(getClass());
private static ThreadLocal<StopWatch> stopWatchLocal = new ThreadLocal<StopWatch>();
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
StopWatch stopWatch = new StopWatch(handler.toString());
stopWatchLocal.set(stopWatch);
stopWatch.start(handler.toString());
String urlString = request.getRequestURL().toString();
if(!urlString.contains("/login")
&&!urlString.contains("/logoff")
&&urlString.contains("/v")){
HttpSession session = request.getSession();
Object name = session.getAttribute(Constants.Other.CUSTOMER_MODEL);
System.out.println("获取Session:"+JSON.toJSONString(name)+"_周期为:"+session.getMaxInactiveInterval());
if(name != null){
return true;
} else {
boolean checkSgin = checkSgin(request,response);
if(checkSgin)
return true;
}
returnJson(response);
return false;
}
RepeatedlyReadRequestWrapper requestWrapper;
if (request instanceof RepeatedlyReadRequestWrapper) {
requestWrapper = (RepeatedlyReadRequestWrapper) request;
log.info("请求Body: {} ", getBodyString(requestWrapper));
}
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception{
RepeatedlyReadRequestWrapper requestWrapper;
if (request instanceof RepeatedlyReadRequestWrapper) {
requestWrapper = (RepeatedlyReadRequestWrapper) request;
log.info("再次请求Body: {} ", getBodyString(requestWrapper));
}
}
public void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception{
}
private void returnJson(HttpServletResponse response) throws Exception{
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try {
ResultStatus result = new ResultStatus();
ResultHelperUtil.setFail(result, CloudBasisEnum.LOGIN_OVERTIME.getMsg());
writer = response.getWriter();
writer.write(JSON.toJSONString(result));
} catch (IOException e) {
log.error("response error",e);
} finally {
if (writer != null)
writer.close();
}
}
public boolean checkSgin(HttpServletRequest request,HttpServletResponse response) throws IOException {
BufferedReader reader = request.getReader();
String sgin = "";
String sginTime = "";
StringBuilder sub = new StringBuilder();
String str = "";
while ((str=reader.readLine())!=null){
sub.append(str);
}
if(StringUtils.isNoneBlank(str)){
Map<String,Object> map = JSON.parseObject(str, Map.class);
sgin = MapUtil.getStringValue(map,"sgin");
sginTime = MapUtil.getStringValue(map,"sginTime");
}
if(StringUtils.isBlank(sgin)||StringUtils.isBlank(sginTime))
return false;
if(StringUtils.isBlank(sgin)
||StringUtils.isBlank(sginTime)
||!EncryptionUtil.unSgin(sgin,sginTime)){
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try {
ResultStatus result = new ResultStatus();
result.setCode(CloudBasisEnum.NOT_JURISDICTION.getCode());
result.setMsg(CloudBasisEnum.NOT_JURISDICTION.getMsg());
writer = response.getWriter();
writer.write(JSON.toJSONString(result));
} catch (IOException e) {
log.error("response error",e);
} finally {
if (writer != null)
writer.close();
}
return false;
}
return true;
}
public static String getBodyString(final ServletRequest request) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = cloneInputStream(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();
inputStream = null;
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
reader = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
public static InputStream cloneInputStream(ServletInputStream inputStream) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
InputStream byteArrayInputStream = null;
try {
while ((len = inputStream.read(buffer)) > -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
byteArrayOutputStream.flush();
byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != byteArrayOutputStream) {
byteArrayOutputStream.close();
byteArrayOutputStream = null;
}
} catch (Exception e){
e.printStackTrace();
}
}
return byteArrayInputStream;
}
}