以下是我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
?
答案 0 :(得分:19)
JSF使用托管bean名称作为密钥将会话作用域托管bean存储为会话属性。所以以下内容应该有效(假设JSF在会话之前已经创建了bean):
MyBean myBean = (MyBean) request.getSession().getAttribute("myBean");
那就是说,我觉得你正在寻找解决方案的错误方向。你也可以这样做:
<a href="profile.jsf?userId=123">
在与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));
// ...
}
答案 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和朋友。