如何从Servlet访问托管bean和会话bean

时间:2010-10-13 00:45:33

标签: java jsf servlets jsf-2

以下是我commandLink的工作方式

 <p:dataTable value="#{myBean.users}" var="item">
     <p:column>
         <h:commandLink value="#{item.name}" action="#{myBean.setSelectedUser(item)}" />     
     </p:column>
 </p:dataTable>

然后在myBean.java

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

假设用户名为Peter。然后,如果我点击Peter,我会将selectedUser设置为Peter的用户对象,然后重定向到配置文件页面,该页面现在呈现来自selectedUser的信息。我想仅使用<h:outputText>创建相同的效果,因此我想到了GET请求。所以我这样做

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

然后text(String name, Long id)方法返回

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

剩下的就是创建一个servlet,捕获id,查询数据库以获取user对象,设置为selectedUser,重定向。 所以这是我的servlet

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

现在我有id,如何访问我的会话bean以查询user的数据库,然后访问托管bean以将user设置为selectedUser ,然后重定向到profile.jsf

2 个答案:

答案 0 :(得分:19)

JSF使用托管bean名称作为密钥将会话作用域托管bean存储为会话属性。所以以下内容应该有效(假设JSF在会话之前已经创建了bean):

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

那就是说,我觉得你正在寻找解决方案的错误方向。你也可以这样做:

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

在与profile.jsf

关联的请求范围内的bean中包含以下内容
@ManagedProperty(value="#{param.userId}")
private Long userId;

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

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

答案 1 :(得分:4)

如果您正在使用像Glassfish v3这样的Java EE 6应用服务器,则可以在servlet的字段中添加注入 EJB 注释。有人喜欢这样:

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

请记住,这些注释是上下文和依赖注入 CDI 的一部分,因此,您必须添加 beans.xml 部署描述符。

但是,如果您不能使用 CDI 注释,请在 java:comp / BeanManager 中查找 BeanManager 界面并使用它访问(仅限)托管bean (在托管bean中,您可以使用 @EJB 注释注入会话bean )。另请记住添加 beans.xml 部署描述符。

实用程序类查找 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);
    }
}

在servlet的 processRequest 方法或等效方法中使用实用程序类:

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();
}

带有会话bean 托管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!";
    }
}

我不知道实用程序类中的代码是否100%正确,但是有效。此外,代码不会检查 NullPointerException和朋友