@RequestBody注解參數(shù)的接口以 application/json 作為請求頭Content-Type的類型肛响,以輸入流的方式讀取json類型參數(shù)告喊,因為是輸入流麸拄,所以只能讀取一次,在一些項目中黔姜,我們可能需要在controller之前使用到請求參數(shù)拢切,比如攔截器、過濾器秆吵、Aspect淮椰,為了滿足這些多次獲取輸入流中參數(shù)需求,利用攔截器對request進行改造;
創(chuàng)建一個類ContentCachingRequestWrapper 繼承 HttpServletRequestWrapper
包括一個內(nèi)部類RequestCachingInputStream 繼承 ServletInputStream
構(gòu)造參數(shù)為HttpServletRequest 的構(gòu)造方法
將輸入流中數(shù)據(jù)緩存到ByteArrayInputStream中主穗,可以重復(fù)讀取
import org.apache.commons.io.IOUtils;
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;
public class ContentCachingRequestWrapper extends HttpServletRequestWrapper{
private byte[] body;
private BufferedReader reader;
private ServletInputStream inputStream;
public ContentCachingRequestWrapper(HttpServletRequest request) throws IOException{
super(request);
loadBody(request);
}
private void loadBody(HttpServletRequest request) throws IOException{
body = IOUtils.toByteArray(request.getInputStream());
inputStream = new RequestCachingInputStream(body);
}
public byte[] getBody() {
return body;
}
public void setBody(byte[] body){
this.body=body;
inputStream = new RequestCachingInputStream(body);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (inputStream != null) {
ServletInputStream tmp = this.inputStream;
this.inputStream = new RequestCachingInputStream(body);
return tmp;
return inputStream;
}
return super.getInputStream();
}
@Override
public BufferedReader getReader() throws IOException {
if (reader == null) {
reader = new BufferedReader(new InputStreamReader(inputStream, getCharacterEncoding()));
}
return reader;
}
private static class RequestCachingInputStream extends ServletInputStream {
private final ByteArrayInputStream inputStream;
public RequestCachingInputStream(byte[] bytes) {
inputStream = new ByteArrayInputStream(bytes);
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public boolean isFinished() {
return inputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readlistener) {
}
}
}
創(chuàng)建過濾器配置類
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
import sjy.notion.notion.app.filter.ValidateFilter;
import javax.servlet.DispatcherType;
/**
* @author zhang
* @date 2019/3/29 上午12:01
*/
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean validateFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new ValidateFilter());
registration.addUrlPatterns("/*");
registration.setName("validateFilter");
registration.setOrder(Integer.MAX_VALUE);
return registration;
}
}
創(chuàng)建過濾器過濾request
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class ValidateFilter implements Filter {
private static Logger log = LoggerFactory.getLogger(ValidateFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);
chain.doFilter(requestWrapper, response);
}
}
request.getInputStream() 就可以重復(fù)獲取數(shù)據(jù)