2011-09-23 31 views
24

Chỉ từ một vài tìm kiếm, điều này có vẻ như là một vấn đề đã xảy ra trong một thời gian. Tôi đã viết một FacesConverter trông giống như sau. Đối tượng Danh mục là thực thể JPA và CategoryControl là DAO tìm nạp nó.Tiêm CDI vào một FacesConverter

@FacesConverter(value = "categoryConverter") 
public class CategoryConverter implements Converter { 

@Inject private CategoryControl cc; 

public CategoryConverter() { } 

@Override 
public Object getAsObject(FacesContext context, UIComponent component, String value) { 
    if (cc != null) return cc.getByName(value); 
    System.out.println("CategoryConverter().getAsObject(): no injection!"); 
    return null; 
} 

@Override 
public String getAsString(FacesContext context, UIComponent component, Object value) { 
    if (!(value instanceof Category)) return null; 
    return ((Category) value).getName(); 
} 

} 

Như bạn có thể đoán bây giờ, tôi không bao giờ được tiêm. Tôi nhận được giải pháp này từ this page, giống như sau:

Workaround for this problem: create this method in your localeController: 

public Converter getConverter() 
{ 
    return FacesContext.getCurrentInstance().getApplication().createConverter("localeConverter"); 
} 

and use converter="#{localeController.converter}" in your h:selectOneMenu. 

Tuy nhiên tôi cũng không thể thực hiện công việc này. Bean sao lưu của tôi tạo và trả về một trình biến đổi, nhưng nó không nhận được đối tượng được tiêm vào nó.

Tôi đang sử dụng MyFaces CODI 1.0.1. Với hộp chứa GlassFish/Weld hiện tại. Bất cứ ai có thể đề xuất một giải pháp trước khi tôi tái mã để không sử dụng một Converter?

Trả lời

53

Thay

@FacesConverter(value = "categoryConverter") 

bởi

@Named 

và sử dụng

<h:inputSomething converter="#{categoryConverter}" /> 

hoặc

<f:converter binding="#{categoryConverter}" /> 

inste quảng cáo của

<h:inputSomething converter="categoryConverter" /> 

hoặc

<f:converter converterId="categoryConverter" /> 

Bằng cách này, vấn đề tương tự tồn tại cho @EJB bên trong một @FacesConverter. Tuy nhiên nó cung cấp một cách để được lấy bởi JNDI bằng tay. Xem thêm Communication in JSF 2.0 - Getting an EJB in @FacesConverter and @FacesValidator. Bằng cách này, bạn có thể sử dụng @FacesConverter(forClass=Category.class) mà không cần xác định thủ công mọi lúc. Thật không may tôi không thể nói từ đầu của đầu như thế nào để nhận ra rằng đối với đậu CDI.


Cập nhật: nếu bạn tình cờ sử dụng JSF tiện ích thư viện OmniFaces, kể từ phiên bản 1.6 là bổ sung hỗ trợ trong suốt cho việc sử dụng @Inject@EJB trong một lớp học @FacesConverter mà không bất kỳ cấu hình bổ sung hoặc chú thích. Xem thêm the CDI @FacesConverter showcase example.

+3

Vâng, tôi sẽ được dambed. Tôi đã thực hiện một giải pháp cơ bản để gọi ứng dụng để đánh giá một biểu thức từ bên trong trình biến đổi, nhưng tôi nghĩ điều này là thanh lịch hơn. Vì vậy, tôi có một câu hỏi @BalusC - không phải là về thời gian bạn đã viết một cuốn sách trên JSF? – AlanObject

+3

Bạn được chào đón. Đối với cuốn sách, bạn không phải là người đầu tiên hỏi điều này ... – BalusC

+0

Cũng không phải là bạn sẽ phải viết nhiều - chỉ cần chỉnh sửa tất cả nội dung bạn đã viết. Nghiêm túc tôi đã nghĩ đến một phác thảo cho một cuốn sách nếu bạn quan tâm đến một sự hợp tác chỉ cho tôi biết. – AlanObject

3

Chỉ cần sử dụng @Advanced of CODI cho @FacesConverter của bạn, xem Wiki.

Ngay sau khi trình chuyển đổi hoặc trình xác thực được chú thích bằng @Advanced, bạn có thể sử dụng @Inject.

2

mỗi BalusC của câu trả lời here, tôi quyết định thêm JSF (requestscoped) đậu mà chỉ chứa @FacesConverter và Chuyển đổi để giải quyết vấn đề này trong ứng dụng của tôi, vì tôi đang chuyển từ JSF quản lý đậu để CDI đậu được quản lý quản lý.

Tôi đã thử CODI @Advanced với @FacesConverter, nhưng nó không tiêm đậu chút nào.

6

@Inject Chú thích chỉ hoạt động trong các phiên bản do CDI quản lý. Nếu bạn muốn sử dụng các tính năng CDI bên trong một cá thể được quản lý không phải CDI (Giống như Trình xác thực JSF hoặc Bộ chuyển đổi JSF), bạn có thể lập trình ngược lại với API CDI.

Tính năng này chỉ hoạt động trong ít nhất máy chủ Java EE 7 + CDI 1.1.

@FacesValidator("userNameValidator") 
public class UserNameValidator implements Validator { 

    private UserService userService; 

    public UserNameValidator(){ 
     this.userService = CDI.current().select(UserService.class).get(); 
    } 

    @Override 
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { 
    .... 
    } 
} 

https://docs.oracle.com/javaee/7/api/javax/enterprise/inject/spi/CDI.html

Với tất cả các AnnotationHell ở những người Java EE quên làm thế nào để viết mã.

Các vấn đề liên quan