• springboot 如何在请求进入controller之前改变body中的值


    springboot 如何在请求进入controller之前改变body中的值

    • 拦截器HandlerInterceptorAdapter

    通过继承HandlerInterceptorAdapter 拦截器,可以重写preHandle方法,但是在这个方法里直接对HttpServletRequest中的body进行更改是无效的。HttpServletRequest请求实际上并没有改变。

    • HttpServletRequestWrapper 请求包装类

    通过继承HttpServletRequestWrapper 可以重写自己的包装类。如:

    public class MultiReadHttpServletRequestWrapper extends HttpServletRequestWrapper {
        private String tempBody;
    
        public MultiReadHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            tempBody = AbstractRequestUtils.getRequestBody(request);
        }
    
        @Override
        public ServletInputStream getInputStream() {
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(tempBody.getBytes());
            return new ServletInputStream() {
                @Override
                public boolean isReady() {
                    return false;
                }
    
                @Override
                public int readLine(byte[] b, int off, int len) throws IOException {
                    return super.readLine(b, off, len);
                }
    
                @Override
                public boolean isFinished() {
                    return false;
                }
    
                @Override
                public void setReadListener(ReadListener readListener) {
    
                }
    
                @Override
                public int read() {
                    return byteArrayInputStream.read();
                }
            };
        }
    
        @Override
        public BufferedReader getReader() {
            return new BufferedReader(new InputStreamReader(this.getInputStream()));
        }
    
        public String getBody() {
            return this.tempBody;
        }
    
        public void setBody(String body) {
            this.tempBody = body;
        }
    
    }
    

    在这里面定义了一个tempbody,可以防止出现流只能被读取一次而出现的流重读错误。

    • 定义一个过滤器,以过滤相应请求,让它们使用包装过的HttpServletRequest。
    @Slf4j
    public class RequestWrapperFilter implements Filter {
    
        @Override
        public void init(FilterConfig config) {
            log.info("==>RequestWrapperFilter启动");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws java.io.IOException, ServletException {
            MultiReadHttpServletRequestWrapper requestWrapper = new MultiReadHttpServletRequestWrapper((HttpServletRequest) request);
            chain.doFilter(requestWrapper, response);
        }
    
        @Override
        public void destroy() {
        }
    }
    
    • 在WebMvcConfigurer中注册过滤器(这里也注册了最开始的拦截器)
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Bean
        public WebInterceptor webInterceptor() {
            return new WebInterceptor();
        }
    
        @Bean
        public FilterRegistrationBean addRequestWrapperFilter() {
            FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
            registration.setFilter(new RequestWrapperFilter());
            registration.setName("RequestWrapperFilter");
            registration.addUrlPatterns("/interest/*");
            registration.setOrder(1);
            return registration;
        }
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(webInterceptor()).addPathPatterns("/interest/**");
        }
    }
    
    • 在拦截器中对body中的值进行修改
    @Slf4j
    public class WebInterceptor extends HandlerInterceptorAdapter {
        @Resource
        private IpVisitService ipVisitService;
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            String ip = HttpUtils.getRemoteIP(request);
    
            log.info("!!!!!!!!!!!!!!!!currentIp:{}", ip);
    
            MultiReadHttpServletRequestWrapper requestWrapper = (MultiReadHttpServletRequestWrapper) request;
            String body = requestWrapper.getBody();
            Preconditions.checkArgument(!StringUtils.isEmpty(body), "请求参数有误!");
            BaseReq baseReq = JSON.parseObject(body, BaseReq.class);
            baseReq.setIp(ip);
            requestWrapper.setBody(JSON.toJSONString(baseReq));
            return true;
        }
    
    }
    

    经过实验,证明修改成功!

  • 相关阅读:
    Android 使用MediaPlayer 播放 视频
    Android加载asset的db
    MAC SVN 基本设置 终端命令
    AFNetWork 简单实用demo
    IntelliJ IDEA导出Java 可执行Jar包
    Xcode快速排错
    Listview多tab上滑悬浮
    N最短路径分词
    进程监控工具supervisor
    nginx配置指南
  • 原文地址:https://www.cnblogs.com/fruitknife/p/12598480.html
Copyright © 2020-2023  润新知