如何在两个或多个Servlet之间共享变量或对象?


39

我想知道是否有方法在两个或多个Servlet之间共享变量或对象,我的意思是一些“标准”方式。我想这不是一个好的做法,但是可以更简单地构建原型。

我不知道这是否取决于所使用的技术,但我会用Tomcat 5.5


我想分享一个简单的类的对象(只是公共属性,一个字符串vector,整数等)。我的意图是有一个像DB中的静态数据,当Tomcat停止时显然会丢失。 (它只是用于测试)

  0

它很大程度上取决于它是什么样的对象/变量。变量是否属于一个类,并且您只需要访问?这是一个常数吗?一个例子会很好。 23 9月. 082008-09-23 20:34:14

  0

我希望这有助于:) 23 9月. 082008-09-23 20:43:24

74

我认为你要找的是请求,会话或应用程序数据。

在一个servlet可以作为一个属性对象添加到请求对象,会话对象或servlet上下文对象:

protected void doGet(HttpServletRequest request, HttpServletResponse response) { 
    String shared = "shared"; 
    request.setAttribute("sharedId", shared); // add to request 
    request.getSession().setAttribute("sharedId", shared); // add to session 
    this.getServletConfig().getServletContext().setAttribute("sharedId", shared); // add to application context 
    request.getRequestDispatcher("/URLofOtherServlet").forward(request, response); 
} 

如果你把它放在请求对象将是提供给的servlet,被转发,直到请求完成:

request.getAttribute("sharedId"); 

如果你把它放在会议也将提供给所有servlet向前发展,但该值将被捆绑到用户:

request.getSession().getAttribute("sharedId"); 

直到会话基于用户的不活动而到期。

是由您重置:在应用程序运行时

request.getSession().removeAttribute("sharedId"); 

如果你把它放在servlet上下文也将可用:

request.getSession().invalidate(); 

或者一个servlet的从范围中删除

this.getServletConfig().getServletContext().getAttribute("sharedId"); 

直到你删除它:

this.getServletConfig().getServletContext().removeAttribute("sharedId"); 
  0

你可以请你扩展你的ServletContext的答案吗? 23 9月. 082008-09-23 20:57:28

+1

或'getServletContext()'而不是'this.getServletConfig()。getServletContext()'... 10 11月. 152015-11-10 08:55:26

  0

@William我怎样才能传递别的东西比字符串f.e.来自我创建自己的课程的对象? 26 11月. 152015-11-26 08:35:12

  0

@Dongo我会诚实的说,自从我使用过servlet以来,这已经很长时间了,但是如果我记得正确的时候,我使用了一个字符串作为例子,它可以是任何对象。 27 11月. 152015-11-27 17:56:51


1

难道你不能只把对象放在HttpSession中,然后通过它在每个servlet中的属性名来引用它?

e.g:

getSession().setAttribute("thing", object); 

...然后在另一个servlet:

Object obj = getSession.getAttribute("thing"); 
  0

doesnt对象必须是可序列化的才能工作? 06 9月. 132013-09-06 16:56:04


7

取决于预期的数据的使用范围。

如果数据仅用于每个用户,如用户登录信息,页面访问次数等,请使用会话对象 (httpServletRequest.getSession().get/setAttribute(String [,Object]) )

如果跨多个用户(总网页命中,工作线程等)的数据相同,则使用ServletContext属性。 getServletContext()。get/setAttribute(String [,Object]))这只会在同一个war文件/ web应用程序中工作。请注意,这些数据在重新启动时也不会持久。

  0

如果你不小心,使用ServletContext可能很容易让你陷入麻烦。例如,您无法使用它以简单的方式实现页面命中计数:从上下文获取当前页面命中数,将其增加并将值设置为上下文。多线程杀死了这个解决方案。 23 9月. 082008-09-23 21:06:49

  0

元批评 - 问题是要求支持数据存储应该通过事务处理的功能。有关ACID的投诉应导致使用ACID数据服务。 ServletContext和Session以某种方式违反了所有的ACID。 24 9月. 082008-09-24 19:46:05


8

把它放在3个不同的范围之一。

要求 - 持续的请求生命

会议 - 持续的用户会话的生命

应用 - 一直持续到applciation关闭

您可以通过HttpServletRequest的变量是访问所有这些作用域传入的方法延伸从HttpServlet class


2

另一个选项,共享数据之间的上下文...

share-data-between-servlets-on-tomcat

<Context path="/myApp1" docBase="myApp1" crossContext="true"/> 
    <Context path="/myApp2" docBase="myApp2" crossContext="true"/> 

在myApp1:

ServletContext sc = getServletContext(); 
    sc.setAttribute("attribute", "value"); 

在myApp2:

ServletContext sc = getServletContext("/myApp1"); 
    String anwser = (String)sc.getAttribute("attribute"); 

0

这里是我是如何做到这与码头。

https://stackoverflow.com/a/46968645/1287091

使用服务器上下文中,其中一个单是一个嵌入式Jetty服务器的启动过程中写入和共享服务器的生活中的所有web应用中。假设在上下文中只有一个编写器 - 也可以用来在webapps之间共享对象/数据 - 否则您需要注意并发性。