为什么JSF将字符串值放入映射<;。。。,整数>;?如何解决这个问题?

为什么JSF将字符串值放入映射<;。。。,整数>;?如何解决这个问题?,jsf,generics,jsf-2,primefaces,el,Jsf,Generics,Jsf 2,Primefaces,El,一开始,我有一些例外。当我找到源代码时,我发现我的Map中的值实际上是字符串 我做了以下实验来检查PrimeFaces的使用是否是我的问题: <h:form> <p:spinner value="#{testBean.integer}" /> <h:inputText value="#{testBean.integer}" /> <p:spinner value="#{testBean.mapInt[0]}" />

一开始,我有一些例外。当我找到源代码时,我发现我的
Map
中的值实际上是字符串

我做了以下实验来检查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>
第一个
甚至不需要通过密码来强制数字输入

我猜JSF在内部使用反射将字段的输入字符串转换为正确的类型。如果是这样,那么泛型的类型擦除可能允许它将
字符串
放在
整数
应该放在的位置。这可能就是为什么
integer
不会出现问题的原因,它属于
integer
类型,而不是泛型类型

我说的对吗

我的问题是:我如何轻松地解决它


我对JSF非常陌生,我在寻找解决方案时听说了转换器。我是否必须创建自定义转换器来强制调用输入字段上的
Integer.valueOf(String)
?我在哪里可以找到如何做到这一点是否有更简单的解决方案

您的具体问题是由于Java泛型类型信息仅在编译时存在,因此在运行时完全不存在,EL表达式仅在运行时求值,因此在编译时不求值。实际上,EL看不到任何泛型类型信息

运行期间所有EL看到的基本上都是
映射
,而不是
映射
。因此,除非您明确指定一个
转换器
,否则JSF/EL将假定它是与提交的值相同的标准类型,该值被提取为:a
字符串

解决方案相对简单:显式指定转换器。对于
Integer
类,可以使用具有转换器ID的JSF内置


@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
<p:spinner value="#{testBean.mapInt[0]}" converter="javax.faces.Integer" />