开发者

How to access managed bean and session bean from Servlet [duplicate]

开发者 https://www.devze.com 2023-01-19 22:46 出处:网络
This question already has answers here: Get JSF managed bean by name in any Servlet related class (6 answers)
This question already has answers here: Get JSF managed bean by name in any Servlet related class (6 answers) Closed 7 years ago.

Here is how my commandLink work

 <p:dataTable value="#{myBean.users}" var="item">
     <p:column>
         <h:commandLink value="#{item.name}" action="#{myBean.setSelectedUser(item)}" />     
     </p:column&g开发者_运维问答t;
 </p:dataTable>

then in myBean.java

 public String setSelectedUser(User user){
     this.selectedUser = user;
     return "Profile";
 }

Let assume the user name is Peter. Then if I click on Peter, I will set the selectedUser to be Peter's User Object, then redirect to the profile page, which now render information from selectedUser. I want to create that same effect only using <h:outputText>, so GET request come to mind. So I do this

 <h:outputText value="{myBean.text(item.name,item.id)}" />

then the text(String name, Long id) method just return

"<a href=\"someURL?userId=\"" + id + ">" + name + "</a>"

all that left is creating a servlet, catch that id, query the database to get the user object, set to selectedUser, the redirect. So here is my servlet

public class myServlet extends HttpServlet { 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Long userId = Long.parseLong(request.getParameter("userId"));
    }
}

Now I have the id, how do I access my session bean to query the database for the user, then access managed bean to set the user to selectedUser, then redirect to profile.jsf?


JSF stores session scoped managed beans as session attribute using managed bean name as key. So the following should work (assuming that JSF has already created the bean before in the session):

MyBean myBean = (MyBean) request.getSession().getAttribute("myBean");

That said, I have the feeling that you're looking in the wrong direction for the solution. You could also just do like follows:

<a href="profile.jsf?userId=123">

with the following in a request scoped bean associated with profile.jsf

@ManagedProperty(value="#{param.userId}")
private Long userId;

@ManagedProperty(value="#{sessionBean}")
private SessionBean sessionBean;

@PostConstruct
public void init() {
    sessionBean.setUser(em.find(User.class, userId));
    // ...
}


You can add Inject and EJB annotations in servlet's fields if your are using a Java EE 6 Application Server like Glassfish v3. Some like this:

@Inject
private AppManagedBean appmanaged;
@EJB
private SessionBean sessbean;

Remeber, those annotations are part of Context and Dependecy Injection or CDI, so, you must add the beans.xml deployment descriptor.

But, if you can't use the CDI annotations, lookup for the BeanManager interface at java:comp/BeanManager and use it for access (only) managed beans (inside a managed bean you can inject session beans with @EJB annotation). Also remember to add the beans.xml deployment descriptor.

Utility class looking up for java:comp/BeanManager:

package mavenproject4;

import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class ManagedBeans {

    private static final BeanManager beanManager;

    static {
        try {
            InitialContext ic = new InitialContext();
            beanManager = (BeanManager) ic.lookup("java:comp/BeanManager");
        } catch (NamingException ex) {
            throw new IllegalStateException(ex);
        }
    }

    private ManagedBeans() {
    }

    public static <T> T getBean(Class<T> clazz, String name) {
        Set<Bean<?>> beans = beanManager.getBeans(name);
        Bean<? extends Object> resolve = beanManager.resolve(beans);
        CreationalContext<? extends Object> createCreationalContext = beanManager.createCreationalContext(resolve);
        return (T) beanManager.getReference(resolve, clazz, createCreationalContext);
    }
}

Usage of utility class in servlet's processRequest method or equivalent:

response.setContentType("text/html;charset=UTF-8");

AppManagedBean appmanaged = ManagedBeans.getBean(AppManagedBean.class, "app");

PrintWriter out = response.getWriter();
try {
    out.println("<html>");
    out.println("<head>");
    out.println("<title>Servlet BeanManager</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h1>" + appmanaged.getHelloWorld() + "</h1>");
    out.println("</body>");
    out.println("</html>");
} finally {
    out.close();
}

Example of managed bean with injected session bean:

package mavenproject4;

import java.io.Serializable;
import javax.annotation.ManagedBean;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;

@ManagedBean
@ApplicationScoped
@Named("app")
public class AppManagedBean implements Serializable {

    private int counter = 0;
    @EJB
    private SessionBean sessbean;

    public AppManagedBean() {
    }

    public String getHelloWorld() {
        counter++;
        return "Hello World " + counter + " times from Pachuca, Hidalgo, Mexico!";
    }
}

I don't know if the code in utility class is 100% correct, but works. Also the code doesn't check NullPointerException and friends.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号