Servlet 会话 HTTPClient
我得到了一个 Servlet A,其中配置了 HTTPClient - 声明了一个调用 Servlet B 的 GetMethod(基本上将 url 传递给 Servlet B 的构造函数)。
在 Servlet BI 中,我设置了一些会话变量,当 Servlet A 取回控制权时在“execute”方法之后,但 Servlet B 中设置的会话变量返回为 null
Servlet A
doPost(req,res)
{
HTTPClient client = new HTTPClient();
GetMethod get = new GetMethod("/ServletB.do");
client.execute(get);
System.out.println("Value of a is :: " + session.getAttribute("a")) ; //gives a NULL
}
Servlet B
doPost(req,res)
{
HTTPSession session = req.getSession();
session.setAttibute("a",a);
session.setAttibute("b",b);
}
您能否让我知道我可以选择哪些选项来解决此问题?
I got a Servlet A which has a HTTPClient configured in it - declared a GetMethod which calls Servlet B (basically passing the url to the constructor of Servlet B".
In Servlet B I am setting some session vars and when the Servlet A gets back the control after the "execute" method but the session vars set in Servlet B are returning as null.
Servlet A
doPost(req,res)
{
HTTPClient client = new HTTPClient();
GetMethod get = new GetMethod("/ServletB.do");
client.execute(get);
System.out.println("Value of a is :: " + session.getAttribute("a")) ; //gives a NULL
}
Servlet B
doPost(req,res)
{
HTTPSession session = req.getSession();
session.setAttibute("a",a);
session.setAttibute("b",b);
}
Can you please let me know what my options are here to get around this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码至少有两个问题:
您需要将 HTTP 请求中的 servlet A 的会话 id 传递到 servlet B。会话 id 在客户端和服务器之间传递的方式是特定于容器的,但通常是会话id 作为 HTTP cookie 传递。
如果多个 servlet 同时访问同一会话并且其中一个 servlet 添加或替换新属性,则 servlet 规范不保证会话属性中的更改立即对所有 servlet 可见。
您最好的选择可能是将 servlet B 中的业务逻辑移动到一个单独的类,并使用 servlet A 或 servlet B 中的该类。或者您是否有其他奇怪的原因从一个 servlet 到另一个 servlet 进行 HTTP 调用相同的 Web 应用程序而不是简单地进行方法调用?
You have at least two issues with your code:
You need to pass your session id from servlet A in the HTTP request to servlet B. How the session id is passed between the client and server is container specific, but usually the session id is passed as an HTTP cookie.
The servlet specification does not guarantee that changes in the session attributes are immediately visible to all servlets, if several servlets are simultaneously accessing the same session and one of the servlets are adding or replacing a new attribute.
Your best option is probably to move the business logic in servlet B to a separate class and use that class from both servlet A or servlet B. Or do you have some other strange reason for making an HTTP call from one servlet to a different servlet within the same web application instead of simply making a method call?
我可以看到您正在调用从 A 执行“get”,而您已经给出了在 B 中处理“post”的代码。
此外,您还使用会话来检索参数
session.getAttribute("a"))
与 B servlet 看到的“会话”不同。I can see you are calling executing a 'get' from A while you have given code of handling 'post' in B.
Also session you are using to retrieve parameter using
session.getAttribute("a"))
is different than 'session' seen by the B servlet.正确的解决方案取决于这些 servlet 实际运行的位置。
如果这些 servlet 在相同网络服务器和 servletcontext 上运行,则只需使用
RequestDispatcher#include()
。他们将有权访问完全相同的会话。如果这些 Servlet 运行在相同 Web 服务器上,但运行在不同 Servlet 上下文中,那么请考虑共享会话,以便它们共享完全相同的会话。目前还不清楚您使用的是什么 servletcontainer,因此这里只是一个针对 Tomcat 的示例来给您一些提示。只需将两个 webapp 上下文的
crosscontext
属性设置为true
:如果这些 servlet 在不同 Web 服务器上运行,那么您需要将感兴趣的数据作为请求参数传递。这真的是你最好的选择。他们不会也不能共享同一个会话,这将是一个安全漏洞。
如果数据相对较大,则考虑共享数据库,这样您只需将 PK 值作为请求参数传递即可。
The right solution depends on where those servlets are actually running.
If those servlets are running at the same webserver and servletcontext, then just use
RequestDispatcher#include()
. They will have access to exactly the same session.If those servlets are running at the same webserver, but a different servletcontext, then consider sharing the sessions so that they will share exactly the same session. It's unclear what servletcontainer you're using, so here's just a Tomcat-targeted example to give you some hints. Just set the
crosscontext
attribute of the both webapp contexs totrue
:If those servlets are running at a different webserver, then you need to pass the data of interest as request parameters. That's your best bet, really. They won't and can't share the same session, that would be a security hole.
If the data is relatively large, then consider a shared database so that you only need to pass the PK value around as request parameter.