SpringBoot实现任意位置获取HttpServletRequest对象

编辑: admin 分类: java 发布时间: 2021-12-03 来源:互联网
目录
  • 任意位置获取HttpServletRequest对象
    • 方法一
    • 方法二
  • HttpServletRequest只能读取一次的解决

    任意位置获取HttpServletRequest对象

    方法一

    //获取RequestAttributes
     RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
     //从获取RequestAttributes中获取HttpServletRequest的信息
     HttpServletRequest request = (HttpServletRequest)requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);

    方法二

    ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();

    HttpServletRequest只能读取一次的解决

    业务逻辑,通过filter读取请求的request,获取token,并将token传递后面流程使用

    BodyReaderHttpServletRequestWrapper:

    public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
        private final byte[] body;
        public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));
        }
        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
        @Override
        public ServletInputStream getInputStream() throws IOException {
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
            return new ServletInputStream() {
                @Override
                public int read() throws IOException {
                    return byteArrayInputStream.read();
                }
                @Override
                public boolean isFinished() {
                    return false;
                }
                @Override
                public boolean isReady() {
                    return false;
                }
                @Override
                public void setReadListener(ReadListener readListener) {
                }
            };
        }
    }

    RepeatReadFilter:

    /**
     * 封装HttpServletRequest为可重复读取请求
     **/
    public class RepeatReadFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            // 防止流读取一次后就没有了, 所以需要将流继续写出去
            ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
            //获取用户凭证
            String token = httpServletRequest.getHeader(Constants.USER_TOKEN);
            if(StringUtils.isBlank(token)){
                token = httpServletRequest.getParameter(Constants.USER_TOKEN);
            }
            //=================获取json格式的token字段=========================
            String body = HttpHelper.getBodyString(requestWrapper);
            if (StringUtils.isNotBlank(body)) {
                JSONObject jsonObject = JSONObject.parseObject(body);
                Object obj = jsonObject.get("token");
                if (null != obj) {
                    token = obj.toString();
                }
            }
            requestWrapper.setAttribute(Constants.USER_TOKEN,token);
            chain.doFilter(requestWrapper, response);
        }
        @Override
        public void destroy() {
        }
    }
    

    FilterConfig:

    @Configuration
    public class FilterConfig {
        @Bean
        public FilterRegistrationBean registFilter() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new RepeatReadFilter());
            registration.addUrlPatterns("/app/*");
            registration.setName("UrlFilter");
            registration.setOrder(1);
            return registration;
        }
    }
    

    AuthorizationInterceptor:

    @Component
    public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            AuthIgnore annotation;
            if(handler instanceof HandlerMethod) {
                annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
            }else{
                return true;
            }
            //如果有@AuthIgnore注解,则不验证token
            if(annotation != null){
                return true;
            }
            //获取用户凭证
            String token = request.getHeader(Constants.USER_TOKEN);
            if(StringUtils.isBlank(token)){
                token = request.getParameter(Constants.USER_TOKEN);
            }
            if(StringUtils.isBlank(token)){
                Object obj = request.getAttribute(Constants.USER_TOKEN);
                if(null!=obj){
                    token=obj.toString();
                }
            }
            //token凭证为空
            if(StringUtils.isBlank(token)){
                throw new AuthException(Constants.USER_TOKEN + "不能为空", HttpStatus.UNAUTHORIZED.value());
            }
            return true;
        }
    }
    

    WebMvcConfig:

    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
        @Autowired
        private AuthorizationInterceptor authorizationInterceptor;
    //    @Autowired
    //    private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(authorizationInterceptor).addPathPatterns("/**");
            super.addInterceptors(registry);
        }
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            //argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
        }
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            super.configureMessageConverters(converters);
        }
        @Override
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        }
    }
    

    在filter中读取token,在interceptor中进行读取判断使用

    HttpHelper:

    public class HttpHelper {
        /**
         * 获取请求Body
         *
         * @param request
         * @return
         */
        public static String getBodyString(ServletRequest request) {
            StringBuilder sb = new StringBuilder();
            InputStream inputStream = null;
            BufferedReader reader = null;
            try {
                inputStream = 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();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return sb.toString();
        }
    }

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。

    【本文来源:bgp服务器 欢迎转载】