为什么 JSF 将 String 值放入 M​​ap<..., Integer> 中?以及如何解决这个问题?

2023-12-11

起初我得到了一些 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,其类型为Integer,不是泛型类型。

我的说法正确吗?

那么我的问题是:我怎样才能轻松解决这个问题?

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


您的具体问题是由 Java 泛型类型信息仅在编译时存在,因此在运行时完全不存在的性质引起的,并且 EL 表达式仅在运行时评估,因此不在编译时评估。实际上,EL 看不到任何通用类型信息。

所有 EL 在运行时看到的基本上都是Map, not a Map<Integer, Integer>。因此,除非您明确指定Converter,JSF/EL 将假定它与提交的值具有相同的标准类型,该值被提取为HTTP请求参数: a String.

解决方案相对简单:显式指定一个转换器。为了Integer类,您可以使用 JSF 内置IntegerConverter其中有转换器 IDjavax.faces.Integer.

<p:spinner value="#{testBean.mapInt[0]}" converter="javax.faces.Integer" />
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 JSF 将 String 值放入 M​​ap<..., Integer> 中?以及如何解决这个问题? 的相关文章

随机推荐