java - 如何从新线程中的会话中删除属性?
问题描述
我写网络应用程序。有验证码,保存在会话中。创建验证码后,我启动新线程,其中作为参数,我从 servlet 传递 HttpServletRequest。接下来,转发发生在 servlet 中。线程休眠 1 分钟,并从会话中删除验证码属性。但我得到 NullPointerExeption。我认为这是因为前锋被召唤了。如何从该线程中的会话中删除属性?
我的代码:
public class RegisterServlet extends HttpServlet {
private CaptchaHandler captchaHandler = new CaptchaHandler();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
captchaHandler.createCaptcha(req, resp);
new MyThread(req).start();
req.getRequestDispatcher("./register.jsp").forward(req, resp);
}
}
public class MyThread extends Thread{
private HttpServletRequest req;
public MyThread(HttpServletRequest req) {
this.req = req;
}
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
req.getSession().removeAttribute("captcha");
}
}
解决方案
该HttpServletRequest
对象仅在service
您的 servlet(调用该doGet
方法)的方法内有效。请参阅Servlet 规范的第 3.13 节:
开发人员必须意识到,
startAsync
不建议维护对未在上述范围之外调用的请求对象的引用,因为它可能会产生不确定的结果。
大多数 servlet 容器回收请求对象。这就是为什么该getSession()
方法为您提供null
. (几乎)您从 a 获得的所有对象HttpServletRequest
都具有相同的寿命,因此传递对该HttpSession
对象的引用也不是解决方案。
我猜您的最终目的是限制未解决验证码的会话数量。为此,您可以致电:
req.getSession().setMaxInactiveInterval(60);
在您的doGet
方法中并在验证码求解器中恢复更高的值。这样,在 60 秒内未解决验证码的所有会话都将被删除。
推荐阅读
- report - allure 不显示以前报告的报告
- python - 图的项目的依赖项列表中的最短路径
- python - 无法将字典保存到文件
- sql - 在 SQL 中迭代逗号分隔值
- azure - 在 VSCode 中出现错误缺少所需的包“azureml-dataset-runtime”
- python - 在 Django 中,我无法从数据库中的 edit.html 表单中检索 Upload cv、Status、gender 的值,但我可以检索其他字段值
- python - Python构造函数递归混淆
- json - MariaDB 过滤器嵌套的 json 字符串
- javascript - 在反应js中更改幻灯片时暂停视频?
- java - 在 Linux 命令行上运行特定版本的 Java