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

 更新时间:2021年11月16日 14:16:43   作者:梁云亮  
这篇文章主要介绍了SpringBoot实现任意位置获取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();
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring boot如何基于拦截器实现访问权限限制

    Spring boot如何基于拦截器实现访问权限限制

    这篇文章主要介绍了Spring boot如何基于拦截器实现访问权限限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • 深入理解Mybatis中的resultType和resultMap

    深入理解Mybatis中的resultType和resultMap

    这篇文章给大家介绍了mybatis中的resultType和resultMap的用法实例讲解,MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,至于两种用法区别,通过本文一起学习吧
    2016-09-09
  • 如何使用idea里面自带的翻译插件

    如何使用idea里面自带的翻译插件

    这篇文章主要介绍了idea里面自带的翻译插件,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Netty源码解析NioEventLoop创建的构造方法

    Netty源码解析NioEventLoop创建的构造方法

    这篇文章主要介绍了Netty源码解析NioEventLoopGroup之NioEventLoop创建的构造方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • java抛出异常与finally实例解析

    java抛出异常与finally实例解析

    这篇文章主要介绍了java抛出异常与finally实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • 简单介绍区分applet和application的方法

    简单介绍区分applet和application的方法

    applet和application都是Java语言编写出来的应用程序,本文简单介绍了二者的不同之处,需要的朋友可以参考下
    2017-09-09
  • 如何修改FeginCilent定义的服务名到指定服务

    如何修改FeginCilent定义的服务名到指定服务

    这篇文章主要介绍了修改FeginCilent定义的服务名到指定服务的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java生成验证码图片的方法

    java生成验证码图片的方法

    这篇文章主要为大家详细介绍了java生成验证码图片的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • Java8 日期和时间类的基本使用

    Java8 日期和时间类的基本使用

    这篇文章主要介绍了Java 日期和时间类的基本使用,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-08-08
  • 全面了解Java中对于异常的捕捉方法

    全面了解Java中对于异常的捕捉方法

    这篇文章主要全面介绍了Java中对于异常的捕捉方法,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11

最新评论