SpringBoot实现任意位置获取HttpServletRequest对象
作者:梁云亮 发布时间:2023-07-07 10:26:40
标签: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();
}
}
来源:https://hcshow.blog.csdn.net/article/details/119944456


猜你喜欢
- 一:自定义异常类:package 自定义异常; //或者继承RuntimeException(运行时异常) public class MyE
- 用户提出一个需求:当修改产品价格的时候,需要记录操作日志,什么时候做了什么事情。想必这个案例,只要是做过应用系统的小伙伴们,都应该遇到过吧?
- 本文主要介绍我为桌面和 Web 设计的一个超级秘密 Flutter 项目使用了画布和可拖动节点界面。本教程将展示我如何使用堆栈来使用小部件完
- 目录项目结构:1.pom引入mongodb依赖2 配置application.properties3.创建mongodb文档映射实体类Spr
- 偶然在项目中用到播放视频时,需要横屏将视频全屏播放,所以需要监听屏幕的横竖屏切换事件。横竖屏切换监听效果: ConfigChang
- 0 写在前面在实际工作中有一些地方需要用到截取字符串的方法,所以在此记录下截取字符串的几种方法。.substring()StringUtil
- HttpClient是一个客户端的HTTP通信实现库。HttpClient的目标是发送和接收HTTP报文。Http协议的重要性相信不用我多说
- 引言声明:文中的MPChart代指MPAndroidChart.本文主要讲解LineChart中的三个变种Chart,第一个是渐变的Line
- 一、volatile关键字介绍及底层原理1.volatile的特性(内存语义)当一个变量被定义成volatile之后,它将具备两项特性:第一
- 一、需求分析:1、输入一个数组-----------------------------------------》程序要接收一组输入的数组,
- 本文实例讲述了Android返回键功能的实现方法。分享给大家供大家参考。具体如下:在开发android应用时,常常通过按返回键(即keyCo
- 背景介绍在开发应用过程中经常会遇到显示一些不同的字体风格的信息犹如默认的LockScreen上面的时间和充电信息。对于类似的情况,可能第一反
- 1.前言对于一个Android开发者来说,每一个页面都继承一个单独的系统Activity,有时候会带来很多不必要的困扰。比如:每一个页面会有
- 一,描写叙述 在多线程下编程的时候。大家可能会遇到一种需求,就是我想在我开启的线程都结束时,同一时候获取
- 本文实例讲述了Java获取凌晨时间戳的方法。分享给大家供大家参考,具体如下:这两天有一个需求是查询用户匹配的推荐信息,包含一个有效时间段,以
- 一、目标效果聊天会话页的列表效果1、聊天数据不满一屏时,顶部显示所有聊天数据2、插入消息时如果最新消息紧靠列表底部时,则插入消息会使列表向上
- 我就废话不多说了,大家还是直接看代码吧~// 要extends TabActivitypublic class Main_activity
- 一:获取根目录的方法取得控制台应用程序的根目录方法方法1、Environment.CurrentDirectory 取得或设置当前工作目录的
- 题目一(有关传值调用与非法访问)请问运行Test 函数会有什么样的结果?答 :程序运行会崩溃 ! 且存在内存泄漏 ;原因:1.str传给p的
- 最近在做一个 Android 项目,需要用到GPS获取位置信息,从 API 查了一下,发现获取位置信息仅需极其简单的一句即可:getLast