Search code examples
jspservletscdiusebean

Session scoped CDI bean accessed via <jsp:useBean> seems to be a different one than in servlet


I would like to inject CDI SessionScoped bean into JSP page.

import javax.enterprise.context.SessionScoped;
import java.io.Serializable;

@SessionScoped
public class UserSessionBean implements Serializable {

    private String email = "email";

    public UserSessionBean(){}

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

When I use the bean this way it works fine and I see initial value on the JSP page.

<jsp:useBean id="userSessionBean" class="package.UserSessionBean"/>
<jsp:getProperty name="userSessionBean" property="email"/>

The problems occurs when I inject the same bean into a service which I call from some another servlet inside my API. In this case I don't get updated value at the JSP page. Looks like I get different beans in JSP page and inside the service using @Inject annotation

Can anybody advise how it is possible to use the same SessionScoped bean inside JSP and service layer accessed from servlet?


Solution

  • Get rid of <jsp:useBean> and <jsp:getProperty> tags. They predate servlets, EL and CDI. Those tags are intented for JSP pages which doesn't make use of any custom servlet or MVC framework provided servlet. See also a.o. jsp:useBean scope.

    The CDI approach is to simply put @Named annotation on the bean class to give it a name in EL.

    @Named
    @SessionScoped
    public class UserSessionBean implements Serializable {}
    

    The name defaults to decapitalized class name. The above CDI managed bean will thus be available in EL by ${userSessionBean}. This also works in a plain JSP page.

    <p>Email: <c:out value="${userSessionBean.email}" /></p>
    

    That's all. You can keep using @Inject in your service or even servlet to get the same instance. Do note that JSTL <c:out> in above JSP snippet is not strictly necessary for printing the value. You can since JSP 2.0 do as good without it.

    <p>Email: ${userSessionBean.email}</p>
    

    But JSP as a fairly jurassic view technology doesn't have builtin XSS prevention like Facelets has. The <c:out> must be used to escape user-controlled input to prevent potential XSS attack holes. See also a.o. XSS prevention in JSP/Servlet web application.

    Last but not least, make sure that your learning resources are caught up with currently available versions. Those <jsp:useBean> tags are from the previous century.