可能重复:
How do servlets work? Instantiation, session variables and multithreading
我的WebServlet中有一种奇怪的(但可能是预期的)行为。环境是:
--Apache 2.2.x
- Glassfish 3.1.1 + mod_jk
- JSF Mojarra 2.1.3
我有一个抽象的servlet,它实现了一些代码来检查FacesContext / Session,如果有一个特定的@SessionScoped托管bean,如果是,那么用户是否已登录。如果用户已登录,则继续进行文件传递。实现@WebServlet只提供实际的文件下载。
摘要Servlet:
public abstract class SecureDownloadServlet extends HttpServlet {
@EJB
private UserProductBean userProductBean;
private UserInfoView userInfoView = null;
private UserInfoView getUserInfoView(HttpServletRequest req) {
FacesContext context = FacesContext.getCurrentInstance();
if (context != null) {
userInfoView = (UserInfoView) context.getApplication()
.getELResolver().getValue(FacesContext.
getCurrentInstance().getELContext(), null, "userInfoView");
}
if (userInfoView == null) {
userInfoView = (UserInfoView) getServletContext().
getAttribute("userInfoView");
}
if (userInfoView == null) {
userInfoView = (UserInfoView) req.getSession().
getAttribute("userInfoView");
}
return userInfoView;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response)
throws IOException, ServletException {
if (getUserInfoView(req) == null || !getUserInfoView(req).getLoggedIn()) {
response.sendRedirect("message.xhtml?msg=noLogin");
return;
}
doDownload(req, response);
}
public abstract void doDownload(HttpServletRequest req,
HttpServletResponse response)
throws IOException, ServletException;
}
然后我有一个@WebServlet扩展了上面的抽象HttpServlet并实现了抽象方法:
@WebServlet(name = "SecureImageServlet", urlPatterns = {"/print","/m/print"})
public class SecureImageServlet extends SecureDownloadServlet {
@Override
public void doDownload(HttpServletRequest req, HttpServletResponse response)
throws IOException, ServletException {
// some code
}
}
现在问题是:
- 从计算机A登录,然后调用SecureImageServlet servlet以获取文件(即http://www.example.com/print?id=12345)。 userInfoView
会话bean按预期初始化,并传递文件
- 从计算机B,未登录,请致电http://www.example.com/print?id=12345。已经使用计算机A上的用户会话初始化userInfoView
!并且文件也已传送。
看起来WebServlet变成了ApplicationScope或类似的东西。这是@EJB注射吗?
请注意userInfoView
的实例是相同的(调试器中的对象ID显示相同的数字),这意味着计算机B被视为与计算机A相同的用户
编辑格式
答案 0 :(得分:0)
好的,我的一个朋友(没有关于SO :)的帐户)指出了我的错误:
我使用userInfoView
作为类成员,而不是将其保留在请求范围内。我通过删除班级成员来修复它,瞧!