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

作者:梁云亮 时间:2023-07-07 10:26:40 

任意位置获取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();
   }
}

来源:https://hcshow.blog.csdn.net/article/details/119944456

标签:SpringBoot,HttpServletRequest,对象
0
投稿

猜你喜欢

  • mybatis使用foreach查询不出结果也不报错的问题

    2023-11-24 22:36:17
  • 详解Java递归实现树形结构的两种方式

    2023-02-18 07:24:47
  • C#导出Excel的示例详解

    2021-12-03 01:55:51
  • 在项目中直接使用hystrix的流程分析

    2021-10-22 01:55:21
  • Java如何实现压缩文件与解压缩zip文件

    2022-01-28 09:14:00
  • spring如何实现两个xml配置文件间的互调

    2021-06-07 20:50:15
  • 浅谈HashMap中7种遍历方式的性能分析

    2022-02-10 05:39:15
  • Java使用BigDecimal进行高精度计算的示例代码

    2023-03-25 10:35:43
  • C#加密解密文件小工具实现代码

    2021-09-21 07:31:41
  • android自定义环形统计图动画

    2021-06-27 19:52:43
  • C#中使用资源的方法分析

    2022-01-16 16:27:02
  • 浅谈MyBatis 事务管理

    2022-03-22 16:17:11
  • SpringBoot四种读取properties文件的方式(小结)

    2023-10-10 03:25:14
  • SpringMVC项目异常处理机制详解

    2023-03-12 13:13:25
  • SpringMVC解析JSON请求数据问题解析

    2023-06-02 21:41:32
  • 详解docker镜像centos7配置Java运行环境

    2022-03-14 04:44:37
  • RabbitMQ交换机使用场景和消息可靠性总结分析

    2023-10-06 14:00:55
  • JDK1.8中的ConcurrentHashMap源码分析

    2023-11-27 06:02:32
  • Android 两个Fragment之间传递数据实例详解

    2022-06-23 19:30:09
  • java和c#使用hessian通信的方法

    2021-12-12 22:03:46
  • asp之家 软件编程 m.aspxhome.com