关于在子线程中获取不到HttpServletRequest对象的问题

2024-05-26 07:28

本文主要是介绍关于在子线程中获取不到HttpServletRequest对象的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这篇文章主要分享一下项目里遇到的获取request对象为null的问题,具体是在登录的时候触发的邮箱提醒,获取客户端ip地址,然后通过ip地址定位获取定位信息,从而提示账号在哪里登录。

但是登录却发现获取request对象的时候报错了。

 具体的代码如下:这个异常是自己手动抛出的。

package cn.edu.sgu.www.mhxysy.util;import cn.edu.sgu.www.mhxysy.consts.MimeType;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.restful.JsonResult;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import com.alibaba.fastjson.JSON;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** http工具类* @author heyunlin* @version 1.0*/
public class HttpUtils {/*** 获取HttpServletRequest对象* @return HttpServletRequest*/public static HttpServletRequest getRequest() {RequestAttributes attributes = RequestContextHolder.getRequestAttributes();if (attributes != null ) {return ((ServletRequestAttributes) attributes).getRequest();}throw new GlobalException(ResponseCode.ERROR, "获取request对象失败");}}

在项目其他地方也有用这个工具了获取HttpServletRequest对象,都能获取到,觉得很是奇怪。点进去RequestContextHolder这个类的代码里看了一下,好像找到问题了~

这是基于ThreadLocal实现的,所以有了子线程无法访问父线程中设置的数据问题,不知道开发者为什么不用InheritThreadLocal来避免这个问题0v0

于是,把涉及获取request对象ip地址获取的代码放在线程外面,这样就避免了空指针问题了~

package cn.edu.sgu.www.mhxysy.chain.login.impl;import cn.edu.sgu.www.mhxysy.chain.login.UserLoginHandler;
import cn.edu.sgu.www.mhxysy.config.property.EmailProperties;
import cn.edu.sgu.www.mhxysy.config.property.SystemSettingsProperties;
import cn.edu.sgu.www.mhxysy.entity.location.Location;
import cn.edu.sgu.www.mhxysy.util.EmailUtils;
import cn.edu.sgu.www.mhxysy.util.IpUtils;
import cn.edu.sgu.www.mhxysy.util.LocationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;/*** @author heyunlin* @version 1.0*/
@Component
public class EmailSendHandler implements UserLoginHandler {private Object params;private UserLoginHandler next;private final EmailUtils emailUtils;private final EmailProperties emailProperties;private final SystemSettingsProperties systemSettingsProperties;@Autowiredpublic EmailSendHandler(EmailUtils emailUtils,EmailProperties emailProperties,SystemSettingsProperties systemSettingsProperties) {this.emailUtils = emailUtils;this.emailProperties = emailProperties;this.systemSettingsProperties = systemSettingsProperties;}@Overridepublic void handle() {if (emailProperties.isEnable()) {String ip = IpUtils.getIp();String username = (String) params;String zoneId = systemSettingsProperties.getZoneId();// 定义日期格式DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");new Thread(() -> {try {String address = "广东广州";Location location = LocationUtils.getLocation(ip);if (systemSettingsProperties.isUseRealLocation()) {String locationAddress = location.getAddress();if (locationAddress != null) {address = locationAddress;}}String text = "您的账号" + username + "在" + address + "登录了。" +"[" + LocalDateTime.now(ZoneId.of(zoneId)).format(formatter) + "]";emailUtils.sendMessage(text);} catch (Exception e) {e.printStackTrace();}}).start();}if (next != null) {next.handle();}}@Overridepublic void setNext(UserLoginHandler next) {this.next = next;}@Overridepublic void setParams(Object params) {this.params = params;}}

总结:遇到这类问题,就把获取request对象的代码放在主线程中,避免因为ThreadLocal的缺陷导致程序异常。


好了,文章就分享到这里了,看完如果对你有所帮助,不要忘了点赞+收藏哦~

这篇关于关于在子线程中获取不到HttpServletRequest对象的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003808

相关文章

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

使用Python实现获取网页指定内容

《使用Python实现获取网页指定内容》在当今互联网时代,网页数据抓取是一项非常重要的技能,本文将带你从零开始学习如何使用Python获取网页中的指定内容,希望对大家有所帮助... 目录引言1. 网页抓取的基本概念2. python中的网页抓取库3. 安装必要的库4. 发送HTTP请求并获取网页内容5. 解

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

电脑提示找不到openal32.dll文件怎么办? openal32.dll丢失完美修复方法

《电脑提示找不到openal32.dll文件怎么办?openal32.dll丢失完美修复方法》openal32.dll是一种重要的系统文件,当它丢失时,会给我们的电脑带来很大的困扰,很多人都曾经遇到... 在使用电脑过程中,我们常常会遇到一些.dll文件丢失的问题,而openal32.dll的丢失是其中比较

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解

pip无法安装osgeo失败的问题解决

《pip无法安装osgeo失败的问题解决》本文主要介绍了pip无法安装osgeo失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 进入官方提供的扩展包下载网站寻找版本适配的whl文件注意:要选择cp(python版本)和你py