객체를 반환하는 명명 된 생산자 메소드 getNewCustomer
을 가진 명명 된 세션 범위 콩인 CustomerRegistration
가 있습니다. 데이터베이스에서 모든 고객을 목록으로 생성하는 CustomerListProducer
클래스도 있습니다. selectCustomer.xhtml 페이지에서 사용자는 고객 중 한 명을 선택하고 선택을 응용 프로그램에 제출할 수 있습니다. 그런 다음 선택한 고객의 성을 간단히 인쇄합니다.CDI 프로듀서 메쏘드 h : selectOneMenu를 참조하십시오.
이제 facelet 페이지에서 선택한 고객을 #{customerRegistration.newCustomer}
을 통해 참조 할 때만 작동합니다. #{newCustomer}
을 단순히 사용하면 양식을 제출할 때마다 성의 출력은 null
입니다.
여기 무슨 일 이니? 이것은 7.1 장에 따라 예상되는 동작입니까? JSR-299 사양의 빈 인스턴스에 대한 제한 사항입니까?
은 말한다 :
이코드입니다 selectCustomer.xhtml 작동하지... 그러나, 응용 프로그램이 직접 결과 인스턴스가 컨테이너에 의해 관리되지 않고, 컨테이너 인스턴스를 실행시키는 대신 빈 클래스, 를 인스턴스화하는 경우가 아니다 contextual 6.5.2 "빈의 문맥 인스턴스"에 정의 된 인스턴스. 또한 2.1.3 절, "빈에 컨테이너가 제공 한 기능 "에 나열된 기능을 해당 인스턴스 에서 사용할 수 없습니다. 배포 된 응용 프로그램에서 콩을 인스턴스화하고 해당 종속성을 초기화하는 것은 컨테이너 입니다.
Customer.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; } }
:
<?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 : @Producer
의 등록 방법의
@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();
}
}