考虑这个例子。
网页:
<h:form>
<h:outputLabel value="Enter some text:"/>
<h:inputText value="#{testController.vo.testString}" />
<h:inputHidden id="test" value="#{testController.vo.id}" />
<h:commandButton value="Click me" action="#{testController.submitForm}"/>
</h:form>
控制器:
@Named
@SessionScoped
public class TestController implements Serializable {
private static final long serialVersionUID = 1L;
private ValueObject vo = new ValueObject();
public String submitForm() {
return null;
}
public ValueObject getVo() {
return vo;
}
public void setVo(ValueObject vo) {
this.vo = vo;
}
}
ValueObject :
public class ValueObject {
private Long id;
private String testString;
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
如您所见,ValueObject
班级有setId
/ getId
个方法。到目前为止,一切都很好。
现在,我想介绍一个界面:
public interface Identifiable<T> {
T getId();
void setId(T id);
}
让我的ValueObject
实现它:
public class ValueObject implements Identifiable<Long> { // remainder omitted }
ValueObject
类没有任何变化,现在它实现了Identifiable
。但是当我尝试再次提交表单时,我得到以下堆栈跟踪:
Caused by: javax.el.ELException: /index.xhtml @16,61 value="#{testController.vo.id}": java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:139)
at javax.faces.component.UIInput.updateModel(UIInput.java:818)
... 34 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
at com.test.vo.ValueObject.setId(ValueObject.java:1)
如您所见,在更新模型值阶段,尝试调用ClassCastException
方法时抛出setId
。这仅适用于隐藏的输入。如果我尝试通过添加转换器来修改 xhtml ,一切正常:
<h:inputHidden id="test" value="#{testController.vo.id}" converter="javax.faces.Long"/>
那么,当我使ValueObject
实现具有泛型参数的接口时,为什么输入行为会发生变化?这是一个Glassfish的错误吗?
修改
事实证明,它不依赖于输入是否隐藏。可以重现此问题的Glassfish版本 3.1-b43 。