【发布时间】:2011-11-20 11:25:05
【问题描述】:
我有一个命名的会话范围 bean CustomerRegistration,它有一个命名的生产者方法 getNewCustomer,它返回一个 Customer 对象。还有CustomerListProducer 类,它从数据库中生成所有客户作为列表。在 selectCustomer.xhtml 页面上,用户可以选择其中一位客户并将选择提交给应用程序,然后应用程序简单地打印出所选客户的姓氏。
现在,这仅在我通过 #{customerRegistration.newCustomer} 在 facelets 页面上引用所选客户时才有效。当我简单地使用#{newCustomer} 时,每当我提交表单时,姓氏的输出就是null。
这里发生了什么?这是根据 JSR-299 规范的第 7.1 章 对 bean 实例化的限制 的预期行为吗?
上面写着:
... 但是,如果应用程序直接实例化一个 bean 类, 而不是让容器执行实例化,结果 实例不由容器管理,也不是上下文 第 6.5.2 节“bean 的上下文实例”定义的实例。 此外,第 2.1 节“功能”中列出的功能 由容器提供给 bean”将不可用 具体事例。在已部署的应用程序中,它是容器 负责实例化 bean 并初始化它们的 依赖关系。 ...
代码如下:
客户.java:
@javax.persistence.Entity
@Veto
public class Customer implements Serializable, Entity {
private static final long serialVersionUID = 122193054725297662L;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Id
@GeneratedValue()
private Long id;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return firstName + ", " + lastName;
}
@Override
public Long getId() {
return this.id;
}
}
CustomerListProducer.java:
@SessionScoped
public class CustomerListProducer implements Serializable {
@Inject
private EntityManager em;
private List<Customer> customers;
@Inject
@Category("helloworld_as7")
Logger log;
// @Named provides access the return value via the EL variable name
// "members" in the UI (e.g.,
// Facelets or JSP view)
@Produces
@Named
public List<Customer> getCustomers() {
return customers;
}
public void onCustomerListChanged(
@Observes(notifyObserver = Reception.IF_EXISTS) final Customer customer) {
// retrieveAllCustomersOrderedByName();
log.info(customer.toString());
}
@PostConstruct
public void retrieveAllCustomersOrderedByName() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> criteria = cb.createQuery(Customer.class);
Root<Customer> customer = criteria.from(Customer.class);
// Swap criteria statements if you would like to try out type-safe
// criteria queries, a new
// feature in JPA 2.0
// criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
criteria.select(customer).orderBy(cb.asc(customer.get("lastName")));
customers = em.createQuery(criteria).getResultList();
}
}
CustomerRegistration.java:
@Named
@SessionScoped
public class CustomerRegistration implements Serializable {
@Inject
@Category("helloworld_as7")
private Logger log;
private Customer newCustomer;
@Produces
@Named
public Customer getNewCustomer() {
return newCustomer;
}
public void selected() {
log.info("Customer " + newCustomer.getLastName() + " ausgewählt.");
}
@PostConstruct
public void initNewCustomer() {
newCustomer = new Customer();
}
public void setNewCustomer(Customer newCustomer) {
this.newCustomer = newCustomer;
}
}
不工作 selectCustomer.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Auswahl</title>
</h:head>
<h:body>
<h:form>
<h:selectOneMenu value="#{newCustomer}" converter="customerConverter">
<f:selectItems value="#{customers}" var="current"
itemLabel="#{current.firstName}, #{current.lastName}" />
</h:selectOneMenu>
<h:panelGroup id="auswahl">
<h:outputText value="#{newCustomer.lastName}" />
</h:panelGroup>
<h:commandButton value="Klick"
action="#{customerRegistration.selected}" />
</h:form>
</h:body>
</html>
工作 selectCustomer.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Auswahl</title>
</h:head>
<h:body>
<h:form>
<h:selectOneMenu value="#{customerRegistration.newCustomer}" converter="customerConverter">
<f:selectItems value="#{customers}" var="current"
itemLabel="#{current.firstName}, #{current.lastName}" />
</h:selectOneMenu>
<h:panelGroup id="auswahl">
<h:outputText value="#{newCustomer.lastName}" />
</h:panelGroup>
<h:commandButton value="Klick"
action="#{customerRegistration.selected}" />
</h:form>
</h:body>
</html>
CustomerConverter.java:
@SessionScoped
@FacesConverter("customerConverter")
public class CustomerConverter implements Converter, Serializable {
private static final long serialVersionUID = -6093400626095413322L;
@Inject
EntityManager entityManager;
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
Long id = Long.valueOf(value);
return entityManager.find(Customer.class, id);
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
return ((Customer) value).getId().toString();
}
}
【问题讨论】:
标签: jsf jsf-2 cdi jboss-weld