@WebServlet的生命周期/范围

时间:2012-10-04 08:09:29

标签: servlets

  

可能重复:
  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相同的用户

编辑格式

1 个答案:

答案 0 :(得分:0)

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