OmniFaces @Param 无法使用转换器设置基元 属性
OmniFaces @Param fails to use converter to set a primitive property
@Inject @Param(converter = "#{pageConverter}") // or "pageConverter"
private int page;
@Named
@ApplicationScoped
public class PageConverter implements Converter
在 page
上使用 OmniFaces @Param
时出现异常
java.lang.IllegalArgumentException: Can not set int field com.example.Bean.page to null value
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80)
at java.lang.reflect.Field.set(Field.java:758)
at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:94)
...
我的转换器应该会处理这个问题,但 getAsObject
从未被调用过。
这个有效:
<f:metadata>
<f:viewParam name="page" value="#{bean.page}">
<f:converter binding="#{pageConverter}"/>
</f:viewParam>
</f:metadata>
这个问题分为三个方面:
- CDI 本身不支持注入原始默认值(需要自定义生产者)。
@Param
从一开始就从未支持原语(因为实践不佳)。
- 当请求参数完全不存在时,永远不会调用 JSF 转换器。
为了解决 1 和 2,我创建了 issue 266,我会在 2.4 最终版之前完成它。
现在,只需使用 Integer
而不是 int
。不使用基元作为模型属性也被认为是更好的做法,因为您可以使用 null
来区分 "value is never submitted" 和 "value is submitted, but is empty".
此外,JSF 转换器从未像 "default value providers" 那样打算。当请求参数完全不存在时, <f:viewParam>
案例也永远不会触发转换器。所以说 "works" 实际上是不正确的。设置 0
的效果只是 EL 强制转换的结果,不涉及转换器。当您将转换器从您的外壳中完全移除时,会出现完全相同的问题。
@Inject @Param(converter = "#{pageConverter}") // or "pageConverter"
private int page;
@Named
@ApplicationScoped
public class PageConverter implements Converter
在 page
上使用 OmniFaces @Param
时出现异常
java.lang.IllegalArgumentException: Can not set int field com.example.Bean.page to null value
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80)
at java.lang.reflect.Field.set(Field.java:758)
at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:94)
...
我的转换器应该会处理这个问题,但 getAsObject
从未被调用过。
这个有效:
<f:metadata>
<f:viewParam name="page" value="#{bean.page}">
<f:converter binding="#{pageConverter}"/>
</f:viewParam>
</f:metadata>
这个问题分为三个方面:
- CDI 本身不支持注入原始默认值(需要自定义生产者)。
@Param
从一开始就从未支持原语(因为实践不佳)。- 当请求参数完全不存在时,永远不会调用 JSF 转换器。
为了解决 1 和 2,我创建了 issue 266,我会在 2.4 最终版之前完成它。
现在,只需使用 Integer
而不是 int
。不使用基元作为模型属性也被认为是更好的做法,因为您可以使用 null
来区分 "value is never submitted" 和 "value is submitted, but is empty".
此外,JSF 转换器从未像 "default value providers" 那样打算。当请求参数完全不存在时, <f:viewParam>
案例也永远不会触发转换器。所以说 "works" 实际上是不正确的。设置 0
的效果只是 EL 强制转换的结果,不涉及转换器。当您将转换器从您的外壳中完全移除时,会出现完全相同的问题。