0

可能重复:
servlet 是如何工作的?实例化、会话变量和多线程

我的 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=12345userInfoView已经使用计算机 A 上的用户会话进行了初始化!!!文件也交付了。

看起来 WebServlet 变成了 ApplicationScope 或类似的东西。是@EJB 注入吗?请注意,实例userInfoView是相同的(调试器中的对象 ID 显示相同的数字),这意味着计算机 B 被视为与计算机 A 相同的用户

编辑格式

4

1 回答 1

0

好的,我的一个朋友(在 SO 上没有帐户 :))指出了我的错误:
我将userInfoView其用作类成员,而不是将其保留在请求范围内。我通过删除班级成员来修复它,瞧!

于 2012-10-04T10:47:57.550 回答