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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3920069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 06:52:57  来源:igfitidea点击:

How to access managed bean and session bean from Servlet

javajsfservletsjsf-2

提问by Thang Pham

Here is how my commandLinkwork

这是我的commandLink工作方式

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

then in myBean.java

然后在 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 selectedUserto 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

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

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

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

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

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

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

剩下的就是创建一个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"));
    }
}

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 userto selectedUser, then redirect to profile.jsf?

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

采纳答案by BalusC

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):

JSF 将会话范围的托管 bean 存储为会话属性,使用托管 bean 名称作为键。所以下面应该工作(假设 JSF 之前已经在会话中创建了 bean):

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

在与以下关联的请求范围bean中具有以下内容 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));
    // ...
}

回答by Santos Zatarain Vera

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

如果您使用的是 Java EE 6 应用服务器(如 Glassfish v3),则可以在 servlet 的字段中添加InjectEJB注释。有些像这样:

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

Remeber, those annotations are part of Context and Dependecy Injectionor CDI, so, you must add the beans.xmldeployment descriptor.

请记住,这些注释是Context and Dependecy InjectionCDI 的一部分,因此,您必须添加beans.xml部署描述符。

But, if you can't use the CDIannotations, lookup for the BeanManagerinterface at java:comp/BeanManagerand use it for access (only) managed beans(inside a managed bean you can inject session beanswith @EJBannotation). Also remember to add the beans.xmldeployment descriptor.

但是,如果您不能使用CDI批注,请在java:comp/BeanManager 中查找BeanManager接口并将其用于访问(仅)托管 bean(在托管 bean 中,您可以使用@EJB批注注入会话 bean)。还记得添加beans.xml部署描述符。

Utility class looking up for java:comp/BeanManager:

查找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 processRequestmethod or equivalent:

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

Example of managed beanwith injected session bean:

注入会话 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!";
    }
}

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

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