美文网首页
springboot @RequestBody注解 appl

springboot @RequestBody注解 appl

作者: 张建勇9511 | 来源:发表于2019-04-27 10:27 被阅读0次

    @RequestBody注解参数的接口以 application/json 作为请求头Content-Type的类型,以输入流的方式读取json类型参数,因为是输入流,所以只能读取一次,在一些项目中,我们可能需要在controller之前使用到请求参数,比如拦截器、过滤器、Aspect,为了满足这些多次获取输入流中参数需求,利用拦截器对request进行改造;

    创建一个类ContentCachingRequestWrapper 继承 HttpServletRequestWrapper
    包括一个内部类RequestCachingInputStream 继承 ServletInputStream

    构造参数为HttpServletRequest 的构造方法
    将输入流中数据缓存到ByteArrayInputStream中,可以重复读取

    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) {
            }
    
        }
    
    }
    
    

    创建过滤器配置类

    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;
        }
    }
    

    创建过滤器过滤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() 就可以重复获取数据

    相关文章

      网友评论

          本文标题:springboot @RequestBody注解 appl

          本文链接:https://www.haomeiwen.com/subject/onehnqtx.html