我目前正在将 Ed Burns 的 JSF 2.0 教科书中的 Virtual Trainer 示例应用程序从 JSF Managed Beans 转换为 CDI。到目前为止,我遇到的大多数问题都与范围界定和忘记正确注入有关,但现在我正在努力克服与从 RequestMap 中提取 CDI Bean(实际上是实体类)相关的最新障碍。从我目前能够确定的情况来看,似乎可以通过使用 Map 实现提供的样板 .get(String managedbeanname) 方法非常简单地提取请求范围的托管 Bean。但是,对于 CDI,bean 由 Weld 包装在 CreationalContextImp 实例中,即使我已确认它存在于 RequestMap 中,我也无法提取我真正想要的对象。
我发现 BalusC 的一篇文章讨论了使用过滤器类访问 SessionScope 中保存的 CDI bean(如何从过滤器中获取 SessionScoped CDI bean?)似乎有点涉及 - 有没有更简单的解决方案?我也很清楚,我可能会混淆 Managed Bean vs CDI 策略的范围/混合,所以请随时让我直截了当......我也有点不确定以这种方式直接使用实体 Bean 而不是使用正面。这是否会导致我/以后可能会导致我出现问题?
环境:JEE7、Glassfish 4、Netbeans 7.4、Maven EE Web Archetype 与使用 Managed Beans 相关的原始代码已被注释掉。
抽象支持bean类:
@RequestScoped
public abstract class AbstractBacking implements Serializable {
//@ManagedProperty(value="#{facesContext}")
private FacesContext facesContext;
//@ManagedProperty(value="#{requestScope}")
private Map<String, Object> requestMap;
//@ManagedProperty(value="#{sessionScope}")
private Map<String, Object> sessionMap;
@PostConstruct
public void init() {
this.facesContext = FacesContext.getCurrentInstance();
this.sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
this.requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
}
注册页面后台bean:
@Named
@RequestScoped
public class RegisterBacking extends AbstractBacking implements Serializable {
private Object password1;
@Inject
private User newUser;
public String registerUser() {
String result = null;
User newUser = (User) getRequestMap().get("user");
// set the password into the user, because we know the validator was
// successful if we reached here.
newUser.setPassword((String) getRequestMap().get("password1"));
try {
UserRegistry.getCurrentInstance().addUser(newUser);
// Put the current user in the session
setCurrentUser(newUser);
// redirect to the main page
result = "/user/allEvents?faces-redirect=true";
} catch (EntityAccessorException ex) {
getFacesContext().addMessage(null,
new FacesMessage("Error when adding user"
+ ((null != newUser) ? " " + newUser.toString() : "") + "."));
}
return result;
}
用户实体 bean:
@Entity
@Named
@Table(name = "Users")
@RequestScoped
@NamedQueries({
@NamedQuery(name = "user.getAll", query = "select u from User as u"), // @NamedQuery(name = "user.getTrainers", query = "select u from User as u where u.trainer = TRUE"),
// @NamedQuery(name = "user.getUsersForTrainerId", query = "select u from User as u where u.personalTrainerId = :theId")
})
public class User extends AbstractEntity implements Serializable {
protected String firstName;
protected String lastName;
@Temporal(TemporalType.DATE)
protected Date dob;
protected String sex;
protected String email;
private String serviceLevel = "medium";
@Column(name = "userid", nullable = false)
private String userid;
private String password;
private boolean trainer;
private List<Long> subscribedEventIds;
private Long personalTrainerId;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<TrainingSession> sessions;
private boolean sessionsInitialized = false;
public User() {
this.init();
}
public User(String firstName, String lastName,
String sex, Date dob, String email, String serviceLevel,
String userid, String password, boolean isTrainer) {
this.init();
this.setFirstName(firstName);
this.setLastName(lastName);
this.setSex(sex);
this.setDob(dob);
this.setEmail(email);
this.setServiceLevel(serviceLevel);
this.setUserid(userid);
this.setPassword(password);
this.setTrainer(isTrainer);
}
.....
Getters/setters/etc
.....
注册页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template="template.xhtml">
<ui:define name="content">
<h:form prependId="false">
<h:panelGrid columns="3">
<h:outputLabel for="fname" value="First Name:" />
<h:inputText label="First Name"
id="fname" value="#{user.firstName}"
required="true"/>
<h:message for="fname" />
<h:outputLabel for="lname" value="Last Name:" />
<h:inputText label="Last Name"
id="lname" value="#{user.lastName}"
required="true"/>
<h:message for="lname" />
<h:outputLabel for="sex" value="Sex:" />
<h:selectOneRadio label="Sex"
id="sex" value="#{user.sex}" required="true">
<f:selectItem itemLabel="Male" itemValue="male" />
<f:selectItem itemLabel="Female" itemValue="female" />
</h:selectOneRadio>
<h:message for="sex" />
<h:outputLabel for="dob" value="Date of Birth:" />
<h:panelGroup>
<h:inputText label="Date of Birth"
id="dob" value="#{user.dob}" required="true">
<f:convertDateTime pattern="MM-dd-yy" />
</h:inputText> (mm-dd-yy)
</h:panelGroup>
<h:message for="dob" />
<h:outputLabel for="email" value="Email Address:" />
<h:inputText label="Email Address"
id="email" value="#{user.email}" required="true" />
<h:message for="email" />
<h:outputLabel for="slevel" value="Service Level:" />
<h:selectOneMenu label="Service Level" id="slevel"
value="#{user.serviceLevel}">
<f:selectItem itemLabel="Medium" itemValue="medium" />
<f:selectItem itemLabel="Basic" itemValue="basic" />
<f:selectItem itemLabel="Premium" itemValue="premium" />
</h:selectOneMenu>
<h:message for="slevel" />
<h:outputLabel for="userid" value="Userid:" />
<h:inputText required="true" id="userid" value="#{user.userid}" />
<h:message for="userid" />
<h:outputLabel for="password" value="Password:" />
<h:inputSecret required="true" id="password"
validator="#{registerBacking.validatePassword1}"
value="#{requestScope.password1}" />
<h:message for="password" />
<h:outputLabel for="password2" value="Retype Password:" />
<h:inputSecret required="true" id="password2" value="#{requestScope.password2}"
validator="#{registerBacking.validatePassword2}" />
<h:message for="password2" />
</h:panelGrid>
<p><h:commandButton value="Register"
action="#{registerBacking.registerUser}" /></p>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>