Trong một trang "tạo người dùng mới" JSF, tôi có một SelectOneMenu với bộ chuyển đổi tùy chỉnh và một selectItem noSelectionOption như thế này: (mã không liên quan Bỏ qua phần)JSF SelectOneMenu with noSelectionOption sử dụng nhãn làm giá trị?
NewUser.xhtml
<h:form>
<h:selectOneMenu value="#{newUserController.user.department}"
required="true" converter="departmentConverter">
<f:selectItem itemLabel="Select a department" noSelectionOption="true"/>
<f:selectItems value="#{newUserController.departments}"
var="dep" itemLabel="#{dep.name}" itemValue="#{dep}"/>
</h:selectOneMenu>
<p:commandButton action="#{newUserController.saveUser}"
value="#{bundle.Save}"
ajax="false"/>
</h:form>
NewUserController.java
@ManagedBean
@ViewScoped
public class NewUserController implements Serializable {
private static final long serialVersionUID = 10L;
@EJB private UserBean userBean;
private List<Department> departments;
private User user;
public NewUserController() {
}
@PostConstruct
public void init(){
user = new User();
departments = userBean.findAllDepartments();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Department> getDepartments(){
return departments;
}
public String saveUser() {
// Business logic
}
}
DepartmentConverter.java
@FacesConverter(value="departmentConverter")
public class DepartmentConverter extends EntityConverter {
public DepartmentConverter(){
super(Department.class);
}
}
Siêu chuyển đổi cho tất cả các đơn vị
public class EntityConverter<E> implements Converter{
protected Class<E> entityClass;
public EntityConverter(Class<E> type) {
entityClass = type;
}
@Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
try {
InitialContext ic = new InitialContext();
UserBean ub = (UserBean)ic.lookup("java:global/CompetenceRegister/UserBean");
return ub.find(entityClass, getKey(value));
} catch (NamingException e) {
return null;
}
}
Long getKey(String value) {
Long key;
key = Long.valueOf(value);
return key;
}
String getStringKey(Long value) {
StringBuilder sb = new StringBuilder();
sb.append(value);
return sb.toString();
}
@Override
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof AbstractEntity) {
AbstractEntity e = (AbstractEntity) object;
return getStringKey(e.getId());
}
else
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + entityClass.getName());
}
}
Tuy nhiên, khi tôi đăng các hình thức với tùy chọn "Chọn một bộ phận" được lựa chọn, nó sẽ gửi nhãn để getAsObject trong bộ chuyển đổi thay vì null , do đó gây ra trình biến đổi để ném một ngoại lệ trong getKey (cố gắng chuyển đổi một String chứa một id thành Long). Đặt thuộc tính itemValue của selectItem thành null không có hiệu lực. Các mục từ bộ sưu tập hoạt động hoàn hảo với bộ chuyển đổi. Có ai có bất kỳ ý tưởng về những gì đang gây ra điều này?
Cập nhật Điều thú vị mà tôi quên đề cập đến; nếu tôi loại bỏ thuộc tính chuyển đổi khỏi SelectOneMenu, thuộc tính noSelectionAttribute hoạt động như nó cần, nhưng vì trình biến đổi mặc định không biết cách chuyển đổi các đối tượng của tôi, nên bài đăng không thành công khi chọn một bộ phận thực. Điều này có nghĩa là noSelectionOption = true là SUPPOSED để gửi nhãn của nó thay thế và trình chuyển đổi bằng cách nào đó được mong đợi sẽ xử lý nó?
Đây có phải là jsf1 hoặc jsf2 không? –
Sử dụng Jsf 2. Xin lỗi vì không làm rõ. –
@Shervin: 'f: selectItem noSelectionOption' và' f: selectItems var' biểu thị JSF2. – BalusC