2013-02-21 96 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