起初我得到了一些 ClassCastExceptions。当我去源码时,我发现我的值Map<Integer,Integer>
实际上是字符串。
我做了以下实验来检查 PrimeFaces 的使用是否是我的问题:
<h:form>
<p:spinner value="#{testBean.integer}" />
<h:inputText value="#{testBean.integer}" />
<p:spinner value="#{testBean.mapInt[0]}" />
<h:inputText pt:type="number" value="#{testBean.mapInt[1]}" />
<p:commandButton value="Read Map Values" action="#{testBean.checkTypes}" update="@form" />
<p:messages />
</h:form>
我的测试豆:
@ManagedBean
@ViewScoped
public class TestBean implements Serializable {
private HashMap<Integer, Integer> map;
private Integer integer;
@PostConstruct
public void init() {
map = new HashMap<>();
}
public void checkTypes() {
addMsg(null, "integer - Class: " + integer.getClass().getSimpleName());
for (Object key : map.keySet()) {
Object o = map.get(key);
addMsg(null, "map[" + key.toString() + "] - Class: " + o.getClass().getSimpleName());
}
}
private static void addMsg(String client, String msg) {
FacesContext.getCurrentInstance().addMessage(client, new FacesMessage(msg));
System.out.println("msg [" + client + "]: " + msg);
}
//... getters/setters ...
}
消息显示:
integer - Class: Integer
map[0] - Class: String
map[1] - Class: String
第一个<h:inputText>
甚至不需要直通来强制输入数字。
我猜 JSF 在内部使用反射将字段的输入字符串转换为正确的类型。如果是这样,那么也许泛型的类型擦除允许它把一个应该放在String
哪里。Integer
这可能就是为什么问题不会发生的原因integer
,它是 type Integer
,而不是泛型类型。
我说得对吗?
我的问题是:我怎样才能轻松解决它?
我对 JSF 很陌生,我在寻找解决方案时听说过转换器。我是否必须创建一个自定义转换器来强制Integer.valueOf(String)
对输入字段进行调用?我在哪里可以找到如何做到这一点?有没有更简单的解决方案?