2013-02-21 98 views
1

我在我的JSF頁面中有p:selectOneMenu,當我運行我的JSF頁面時,我從Converter類中得到以下異常。轉換器類拋出異常java.lang.IllegalArgumentException

java.lang.IllegalArgumentException: object 5634 is of type java.lang.String; 
expected type: test.entity.Employee 

如何解決此問題?

,我有以下的實體類

@Entity 
public class Employee implements Serializable { 

private String employeeNumber; 
private String employeeName; 

/* getters and setters */ 

EmployeeConverter類

@Component("employeeConverter") 
@FacesConverter(forClass = Employee.class) 

@Inject 
EmployeeService employeeService; 

@Override 
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) { 

    if (value == null || value.length() == 0) { 
     return null; 
    } 
    EmployeeService employeeService= (EmployeeService) facesContext.getApplication().getELResolver(). 
      getValue(facesContext.getELContext(), null, "employeeService"); 
    return employeeService.getEmployees(); 
} 

@Override 
public String getAsString(FacesContext facesContext, UIComponent component, Object object) { 

      if (object == null) { 
       return null; 
      } 
      if (object instanceof Employee) { 
       Employee emp = (Employee) object; 
       String val = emp.getEmployeeNumber(); 
       return val; 
      } else { 
throw new IllegalArgumentException("object " + 
object + " is of type " + object.getClass().getName() + "; expected type: " + 
Employee.class.getName()); 
      } 
} 

和JSF頁面

<p:selectOneMenu value="#{mb.employee}" converter="#{employeeConverter}"> 
<f:selectItems value="#{cmb.employeeList}" var="emp" 
itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeNumber}"/> 
<p:ajax listener="#{mb.handleChange}" process="@this"/> 
</p:selectOneMenu> 

更新1

改進的轉換方法getAsObject

private List<Employee> employee; 

@Override 
    public Object getAsObject(FacesContext facesContext, UIComponent component, 
      String value) { 
     System.out.println("reached in converter"); 
     try { 
      if (value == null || value.length() == 0) { 
       return null; 
      } else { 
       employee = getEmployeeService().getEmployees(); 
       for (Employee emp : employee) { 
        if (emp.getEmployeeNUmber() == value) { 
         return emp; 
        } 
       } 
      } 

     } catch (Exception e) { 
      System.out.println("exception from getAsObject " + e.getMessage());    
     } 
     return null; 
    } 

更新2

ManagedBean 

@PostConstruct 
    public void loadEmployees(){ 

     try {   
      List<Employee> emp = getEmployeeService().getEmployees();   
      employeeList = emp; 

     } 
     catch(Exception e){ 
      e.printStackTrace(); 
      System.out.println("exception from loadEmployees "+e.getMessage()); 
     } 

    } 
+0

我不知道是不是這個問題,但你有'#{emp.emploeeNumber}'錯誤類型。 – 2013-02-21 07:19:52

+0

@XtremeBiker抱歉,這是一個錯字,我糾正了它。 – user75ponic 2013-02-21 07:21:52

+0

你能指定你的'getAsObject'方法嗎? – 2013-02-21 07:23:48

回答

2

在您的getAsObject方法中,您對達到的價值無所作爲。在這裏,你將收到你的#{emp.employeeNumber},所以你必須將它轉換爲Employee(可能你必須實現一個方法,它使用服務定位器通過id加載Employee)並返回對象本身。

您也正在使用EL(#{employeeConverter})引用轉換器,您必須以直接方式執行此操作。最後,元素列表必須由SelectItem組成,以使f:selectItems標籤正常工作。

+0

不知道我該如何做到這一點,我可以使用像'返回KeyFactory.stringToKey(價值);'如上所述[這裏](http://digitaljoel.nerd-herders.com/2010/01/11/jsf- 2-custom-converter /) – user75ponic 2013-02-21 08:21:23

+0

您正在執行'employeeService.getEmployees()'操作。在這裏你擁有所有員工,你的價值是保持選定的員工ID。只需在列表中搜索該ID並返回員工本身。這就是轉換器所做的,他們從收到的'String'中獲得一個對象。 – 2013-02-21 08:35:29

+0

我修改了Converter類的'getAsObject'方法,在我的原始問題中添加了更新1.我仍然得到與前面相同的異常。我在'getAsObject'方法的開始部分放了一個println語句,並且也沒有打印出來。我的修改方法有問題嗎?如果真的讓我知道。 – user75ponic 2013-02-21 10:27:26

3

不要指定字符串的項值,你需要指定轉換後的對象(僱員)本身。

變化itemValue="#{emp}"

見BalusC回答這個question

+0

根本沒有必要這樣做。你可以像你說的那樣傳遞整個對象引用,或者像OP試圖做的那樣傳遞id,但是必須的是你必須以某種方式將對象恢復到轉換器中。看看這個http://digitaljoel.nerd-herders.com/2010/01/11/jsf-2-custom-converter/ – 2013-02-21 07:33:07

+1

我的意思是他需要恢復對象本身並將其指定爲對象。你是對的,他可以通過對象的id,但重點是如果他傳遞了一個字符串,爲什麼他需要一個轉換器呢? – fareed 2013-02-21 07:44:49

+0

我真的很喜歡將整個對象引用作爲值傳遞,但真正的問題在於他的'getAsObject'方法。 – 2013-02-21 07:50:59