IllegalArgumentException:无法将类型为 org.omnifaces.el.ExpressionI



我在类级别使用 OmniFaces 1.11 <o:validateBean /> 时遇到问题 (http://showcase.omnifaces.org/validators/validateBean(

基本上,我正在尝试根据我单击的按钮使用两个验证组来验证相同的 bean:

            <h:commandButton value="Mandatory">
                <o:validateBean value="#{testBean.pojo}" validationGroups="bo.ihm.beans.Mandatory" />
            </h:commandButton>
            <h:commandButton value="Optional">
                <o:validateBean value="#{testBean.pojo}" validationGroups="javax.validation.groups.Default" />
            </h:commandButton>

每当我点击一个按钮时,我都会得到

GRAVE: Exception occured while doing validation.
javax.el.ELException: /testOmnifaces.xhtml @21,74 value="#{testBean.pojo.forain}": java.lang.IllegalArgumentException: Cannot convert PROPERTY of type class org.omnifaces.el.ExpressionInspector$ValueExpressionType to class java.lang.Boolean
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
    at org.omnifaces.el.ExpressionInspector.getValueReference(ExpressionInspector.java:43)
    at org.omnifaces.taghandler.ValidateBean$6.invoke(ValidateBean.java:331)
    at org.omnifaces.taghandler.ValidateBean$6.invoke(ValidateBean.java:326)
    at org.omnifaces.util.Components$ForEach$1.visit(Components.java:508)
    at org.omnifaces.util.Components$ForEach$TypesVisitCallback.visit(Components.java:573)
    at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1689)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
    at javax.faces.component.UIForm.visitTree(UIForm.java:371)
    at org.omnifaces.util.Components$ForEach.invoke(Components.java:541)
    at org.omnifaces.util.Components$ForEach.invoke(Components.java:505)
    at org.omnifaces.taghandler.ValidateBean.forEachInputWithMatchingBase(ValidateBean.java:326)
    at org.omnifaces.taghandler.ValidateBean.access$400(ValidateBean.java:151)
    at org.omnifaces.taghandler.ValidateBean$3.run(ValidateBean.java:286)
    at org.omnifaces.taghandler.ValidateBean$ValidateBeanCallback.invoke(ValidateBean.java:430)
    at org.omnifaces.util.Events$1.invoke(Events.java:278)
    at org.omnifaces.util.Events$4.beforePhase(Events.java:312)
    at org.omnifaces.eventlistener.CallbackPhaseListener.beforePhase(CallbackPhaseListener.java:63)
    at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:696)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:521)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:138)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:564)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:213)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1097)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:448)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:175)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1031)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:200)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:446)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:271)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:246)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.el.ELException: java.lang.IllegalArgumentException: Cannot convert PROPERTY of type class org.omnifaces.el.ExpressionInspector$ValueExpressionType to class java.lang.Boolean
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:229)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    ... 44 more
Caused by: java.lang.IllegalArgumentException: Cannot convert PROPERTY of type class org.omnifaces.el.ExpressionInspector$ValueExpressionType to class java.lang.Boolean
    at com.sun.el.lang.ELSupport.coerceToBoolean(ELSupport.java:189)
    at com.sun.el.lang.ELSupport.coerceToType(ELSupport.java:394)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:227)
    ... 45 more

testWithClassLevelValidation.xhtml :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:o="http://omnifaces.org/ui">
<f:metadata>
    <f:viewAction action="#{testBean.init}" />
</f:metadata>
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Test</title>
</h:head>
<h:body>
    <h:form id="formaliteACCRE">
        <h:panelGrid columns="1" style="width: 100%;">
            <h:panelGrid columns="2" style="width: 100%; display: inline-block;">
                <h:outputLabel for="forain">Yes or No ?</h:outputLabel>
                <h:selectBooleanCheckbox id="forain" value="#{testBean.pojo.forain}">
                    <f:ajax execute="forain" render="groupeDomicile" />
                </h:selectBooleanCheckbox>
            </h:panelGrid>
            <h:panelGroup id="groupeDomicile">
                <h:outputText value="Yes" rendered="#{testBean.pojo.forain}" />
                <h:outputText value="No" rendered="#{not testBean.pojo.forain}" />
            </h:panelGroup>
            <h:inputText id="numeroSecu" value="#{testBean.pojo.numeroSecuriteSociale}" maxlength="13" size="13" />
            <h:inputText id="numeroSecuCle" value="#{testBean.pojo.cleSecuriteSociale}" maxlength="2" size="3" />
            <h:panelGrid columns="2" style="width: 100%; display: inline-block;">
                <h:inputText id="mandatory" value="#{testBean.pojo.mandatory}" maxlength="13" size="13" />
                <h:outputText value="*" style="color:red;" />
            </h:panelGrid>
            <f:ajax execute="@form" render="@form">
                <h:commandButton value="Mandatory">
                    <o:validateBean value="#{testBean.pojo}" validationGroups="bo.ihm.beans.Mandatory" />
                </h:commandButton>
                <h:commandButton value="Optional">
                    <o:validateBean value="#{testBean.pojo}" validationGroups="javax.validation.groups.Default" />
                </h:commandButton>
            </f:ajax>
        </h:panelGrid>
        <ui:remove> ################################################################################################ </ui:remove>
        <ui:remove>                             ===== MESSAGES D'ERREURS =====                                       </ui:remove>
        <ui:remove> ################################################################################################ </ui:remove>
        <h:panelGroup id="messagesErreur">
            <h:panelGrid class="dr-pnl" width="100%" rendered="#{not empty facesContext.messageList}">
                <h:messages style="color:red;" />
            </h:panelGrid>
        </h:panelGroup>
    </h:form>
</h:body>
</html>

测试豆.java :

package bo.ihm.beans;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.validation.Valid;
@ViewScoped
@ManagedBean(name = "testBean")
public class TestBean implements Serializable {
    private static final long serialVersionUID = 1L;
    @Valid
    private Pojo pojo;
    public Pojo getPojo() {
        return pojo;
    }
    public void init() {
        pojo = new Pojo();
        pojo.setNumeroSecuriteSociale("2531257351038");
        pojo.setCleSecuriteSociale("22");
    }
    public void setPojo(final Pojo pPojo) {
        this.pojo = pPojo;
    }
}

Pojo.java :

package bo.ihm.beans;
import org.hibernate.validator.constraints.NotEmpty;
@NumeroSecuriteSociale
public class Pojo {
    private boolean forain;
    private String cleSecuriteSociale;
    private String numeroSecuriteSociale;
    @NotEmpty(groups = Mandatory.class)
    private String mandatory;
    public String getCleSecuriteSociale() {
        return cleSecuriteSociale;
    }
    public String getMandatory() {
        return mandatory;
    }
    public String getNumeroSecuriteSociale() {
        return numeroSecuriteSociale;
    }
    public boolean isForain() {
        return forain;
    }
    public void setCleSecuriteSociale(final String pCleSecuriteSociale) {
        cleSecuriteSociale = pCleSecuriteSociale;
    }
    public void setForain(final boolean pForain) {
        forain = pForain;
    }
    public void setMandatory(final String pMandatory) {
        mandatory = pMandatory;
    }
    public void setNumeroSecuriteSociale(final String pNumeroSecuriteSociale) {
        numeroSecuriteSociale = pNumeroSecuriteSociale;
    }
    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("Pojo [forain=");
        builder.append(forain);
        builder.append(", cleSecuriteSociale=");
        builder.append(cleSecuriteSociale);
        builder.append(", numeroSecuriteSociale=");
        builder.append(numeroSecuriteSociale);
        builder.append(", mandatory=");
        builder.append(mandatory);
        builder.append("]");
        return builder.toString();
    }
}

完整的代码可在 https://github.com/ErwanLeroux/Bo_ihm_test_omnifaces Just Run Clean Jetty:Run-War et 转到 http://localhost:14080/bo_ihm/testWithClassLevelValidation.xhtml

第二页 http://localhost:14080/bo_ihm/testWithoutClassLevelValidation.xhtml 是她来证明类级别约束不起作用,当我单击每当按钮时,我应该会收到如下验证错误消息:"Pojo [forain=false, cleSecuriteSociale=22, numeroSecuriteSociale=2531257351038, 强制性=null] 无效'

事实证明,隐式EL胁迫导致了这一切。我们传递了 ValueExpressionType.PROPERTYValueExpressionType.METHOD 等内部值,以指示 EL 表达式是表示属性(getter/setter(调用还是方法(操作(调用。但是,如果值具有隐式 EL 强制支持,则此方法失败,例如 java.lang.Boolean,EL 将隐式转换为布尔true,例如 "true" 字符串。

这种传递内部值以指示 EL 表达式类型的方法是因为 OmniFaces 2.0 用于在 <o:grapicImage value> 中分解 EL 表达式并提取任何 EL 方法参数,以便它们可以作为 HTTP 查询字符串参数进行转换和传递。这就解释了为什么它在OmniFaces 1.x中仍然运行良好。

根据此提交,此问题已在 OmniFaces 2.2 中修复。

相关内容

  • 没有找到相关文章

最新更新