JSF selectOneMenu 转换器 null 或类转换异常

发布于 2025-01-17 01:32:48 字数 3906 浏览 0 评论 0原文

  • JVM 版本:14.0.2+12-46
  • myfaces-api 2.3.9
  • myfaces-impl 2.3.9
  • apache-tomee-webprofile-8.0.4

我正在使用以下转换器来创建一个简单的实体类:

package view;

import entities.Chain;
import managed.Chains;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@FacesConverter(value = "chainConverter", managed = true)
public class ChainConverter implements Converter<Chain> {
   @Inject
   Chains chains;   

   @Override
   public Chain getAsObject(FacesContext context, UIComponent component, String value) {
        if (value != null && !value.trim().isEmpty()) {
            Chain found = chains.getAvailable().stream()
                      .filter(chain -> chain.getAbbreviation().equals(value))
                      .findFirst()
                      .orElse(null);
            return found;
        }
      return null;
      
   }

   @Override
   public String getAsString(FacesContext context, UIComponent component, Chain chain) {
      if (chain != null && !chain.toString().isEmpty()){
         return chain.getAbbreviation();
         
      }else{
         return null;
         
      }
      
   }

}

给出示例: https://www.primefaces.org/showcase/ui/input/oneMenu.xhtml

我尝试按如下方式使用转换器:

<p:selectOneMenu id="chain" value="#{chains.chain}" var="c" converter="chainConverter">
   <f:selectItem itemLabel="== Selecte Chain ==" />
   <f:selectItems value="#{chains.available}" var="chain" itemLabel="#{chain.name}" itemValue="#{chain}" />
      <p:column>
        #{c.name}
      </p:column>
      <p:ajax event="valueChange" listener="#{inventories.refreshSurvey}" update="@form" />
</p:selectOneMenu>

上面的“converter=”引用会产生以下错误:

org.primefaces.application.exceptionhandler.PrimeExceptionHandler.logException null
    java.lang.NullPointerException
        at org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsString(FacesConverterCDIWrapper.java:69)
        at org.primefaces.renderkit.SelectRenderer.getOptionAsString(SelectRenderer.java:207)
        at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeOption(SelectOneMenuRenderer.java:561)
        at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeSelectItems(SelectOneMenuRenderer.java:524)
        at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeHiddenSelect(SelectOneMenuRenderer.java:211)

如果我更改转换器对 el 表达式的引用如下:

 converter="#{chainConverter}"

我收到错误:

org.primefaces.application.exceptionhandler.PrimeExceptionHandler.logException Cannot convert [entities.Chain@928f] of type [class java.lang.String] to [class entities.Chain]
    javax.el.ELException: Cannot convert [entities.Chain@928f] of type [class java.lang.String] to [class entities.Chain]
        at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:548)
        at org.apache.el.parser.AstValue.setValue(AstValue.java:203)
        at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:263)
        at org.apache.webbeans.el22.WrappedValueExpression.setValue(WrappedValueExpression.java:93)
        at org.apache.webbeans.el22.WrappedValueExpression.setValue(WrappedValueExpression.java:93)

然而,最奇怪的是,在一个项目中它可以工作,而在另一个项目中却不能。例如,在此示例项目中,它按预期工作: https://github.com/dannymk/PrimefacesTest

我一直怀疑这个项目中某个地方的库版本存在差异。但是,即使在更改 pom 文件以匹配工作项目 pom 文件后,我也确实无法查明问题。这对我来说绝对是一个令人头疼的问题。

  • JVM Version: 14.0.2+12-46
  • myfaces-api 2.3.9
  • myfaces-impl 2.3.9
  • apache-tomee-webprofile-8.0.4

I am using the following converter for an simple entity class:

package view;

import entities.Chain;
import managed.Chains;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@FacesConverter(value = "chainConverter", managed = true)
public class ChainConverter implements Converter<Chain> {
   @Inject
   Chains chains;   

   @Override
   public Chain getAsObject(FacesContext context, UIComponent component, String value) {
        if (value != null && !value.trim().isEmpty()) {
            Chain found = chains.getAvailable().stream()
                      .filter(chain -> chain.getAbbreviation().equals(value))
                      .findFirst()
                      .orElse(null);
            return found;
        }
      return null;
      
   }

   @Override
   public String getAsString(FacesContext context, UIComponent component, Chain chain) {
      if (chain != null && !chain.toString().isEmpty()){
         return chain.getAbbreviation();
         
      }else{
         return null;
         
      }
      
   }

}

Given the example at: https://www.primefaces.org/showcase/ui/input/oneMenu.xhtml

I try to use the converter as follows:

<p:selectOneMenu id="chain" value="#{chains.chain}" var="c" converter="chainConverter">
   <f:selectItem itemLabel="== Selecte Chain ==" />
   <f:selectItems value="#{chains.available}" var="chain" itemLabel="#{chain.name}" itemValue="#{chain}" />
      <p:column>
        #{c.name}
      </p:column>
      <p:ajax event="valueChange" listener="#{inventories.refreshSurvey}" update="@form" />
</p:selectOneMenu>

The above "converter=" reference produces the following error:

org.primefaces.application.exceptionhandler.PrimeExceptionHandler.logException null
    java.lang.NullPointerException
        at org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsString(FacesConverterCDIWrapper.java:69)
        at org.primefaces.renderkit.SelectRenderer.getOptionAsString(SelectRenderer.java:207)
        at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeOption(SelectOneMenuRenderer.java:561)
        at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeSelectItems(SelectOneMenuRenderer.java:524)
        at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeHiddenSelect(SelectOneMenuRenderer.java:211)

If I change the converter reference to an el expression as follows:

 converter="#{chainConverter}"

I get the error:

org.primefaces.application.exceptionhandler.PrimeExceptionHandler.logException Cannot convert [entities.Chain@928f] of type [class java.lang.String] to [class entities.Chain]
    javax.el.ELException: Cannot convert [entities.Chain@928f] of type [class java.lang.String] to [class entities.Chain]
        at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:548)
        at org.apache.el.parser.AstValue.setValue(AstValue.java:203)
        at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:263)
        at org.apache.webbeans.el22.WrappedValueExpression.setValue(WrappedValueExpression.java:93)
        at org.apache.webbeans.el22.WrappedValueExpression.setValue(WrappedValueExpression.java:93)

However, the weirdest thing is that in one project it works while in the other project it does not. For example in this sample project it works as expected: https://github.com/dannymk/PrimefacesTest

I have a nagging suspicion that there is a difference in a library version someplace in this project. However, I really can't pinpoint the problem even after changing the pom file to match a working projects pom file. This is definitely a head scratcher to me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文