0

Possible Duplicate:
How do servlets work? Instantiation, session variables and multithreading

I have a weird (but probably expected) behaviour in my WebServlet. Environment is:
- Apache 2.2.x
- Glassfish 3.1.1 + mod_jk
- JSF Mojarra 2.1.3

I have an abstract servlet that implements some code to check in the FacesContext/Session if there is a specific @SessionScoped managed bean and if so, whether the user is signed-in. If user is signed-in, then proceeds to the file delivery. The implementing @WebServlet only provides the actual file download.

Abstract 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;

}

Then I have a @WebServlet that extends the above abstract HttpServlet and implements the abstract method:

@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
    }
}

Now here is the issue:
- From computer A, sign in, then call the SecureImageServlet servlet to get a file (i.e. http://www.example.com/print?id=12345). The userInfoView session bean is initialized as expected, and the file is delivered.
- From computer B, without being signed-in, call http://www.example.com/print?id=12345. The userInfoView is already initialized with the session of user on computer A!!! And the file is delivered too.

It looks like the WebServlet becomes ApplicationScope or something like that. Is it the @EJB injection that does that? Note the the instance of userInfoView is the same (the object id in the debugger shows the same number) which means somehow the computer B is seen as the same user as computer A

Edited format

Community
  • 1
  • 1
JScoobyCed
  • 10,203
  • 6
  • 34
  • 58
  • 1
    Related: http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-session-variables-and-multithreading/3106909#3106909 – BalusC Oct 04 '12 at 14:07
  • 1
    By the way, I've removed the JSF tag as this has completely nothing to do with JSF. Servlet is an entirely distinct API. Attempting to get the `FacesContext` in a Servlet class makes also no utter sense. Just remove those lines. – BalusC Oct 04 '12 at 14:08
  • Thanks and yes, I noticed the FacesContext stuff was always null and that trying to get it was not a smart move. I've cleaned it up – JScoobyCed Oct 05 '12 at 03:03

1 Answers1

0

Ok, a friend of mine (without an account on SO :) ) pointed out my mistake:
I am using userInfoView as a class member instead of keeping it within the request scope. I fixed it by removing the class member and voila!

JScoobyCed
  • 10,203
  • 6
  • 34
  • 58
  • 1
    yep, read the lifecycle of a servlet on the SO sevlet page http://stackoverflow.com/tags/servlets/info A servlet is created once and all requests flow through that instance. – Sean Oct 04 '12 at 15:49
  • A shame I did such a code. I knew that but just been working with JSF View/Request scopes and Jersey RESTful Web Services for so long I overlooked that Servlet are not JSF :) – JScoobyCed Oct 05 '12 at 03:06