我创建了一个JIRA小工具。当我只将一个实例放在仪表板上时,它很好。当我将第二个实例放在同一个仪表板上,将其配置为加载不同的数据,然后刷新整个仪表板时,我可以看到它们共享大多数数据 - 就好像他们几乎同时从服务器获取数据一样然后写入相同的javascript变量,然后基于该变量进行渲染。
当它们渲染时,当我知道它们应该完全不同时,它们大多是相同的(我可以看到与实例B中出现的实例A的配置相匹配的值)。
另一种我认为错误的方法是,当我单独刷新每个小工具时,它们会显示正确的数据。但是,当我刷新整个仪表板时,它们显示的内容基本相同。
如何将这些分开?我有一个想法是尝试以下方法:
但是我在第2步遇到了一些麻烦。我有模板文件“/templates/gadgets/my-gadget.vm”的“位置” - 它不是真正的位置,因为没有这样的文件在该路径的服务器上。渲染器期望'location'作为参数。我想加载/templates/gadgets/my-gadget.vm(无论它在哪里),写出一个新的/templates/gadgets/my-gadget..vm,然后将这个新位置传递给渲染器......但是/templates/gadgets/my-gadget.vm不是普通的文件路径。它在哪里?
或者有更好的方法吗?
注意:servlet中没有任何内容标记为static或volatile - servlet中的所有内容都是特定于实例的(因此也是特定于请求的),因此请求之间的出血是在客户端(请参阅有关讨论的注释)这是否正确,并看到tl; dr)的接受答案。
答案 0 :(得分:1)
您在评论中提到您将从HttpServletRequest传入的值存储为服务器端的“实例变量”。问题是JIRA只会实例化servlet对象的单个副本,这意味着您写入实例变量的任何内容都将在请求之间共享。如果两个请求同时进入并且它们被交错,则线程#1将偶然看到来自线程#2的数据,这可能是发生的事情。
解决方案是将所有内容保留在堆栈中。例如,不要写入实例变量,只需在service
方法中声明局部变量,而不是在类范围内保留所有内容。
如果你的servlet类中已经有其他函数正在使用实例变量,你可以修改它们以接收在方法调用期间作为参数传递的值,或者重构并将该代码移动到另一个使用的类中它自己的实例变量(但请确保每次收到请求时都在service()
内显式实例化该类的新对象!)。