IllegalArgumentException:无法将类型为org.omnifaces.el.E​​xpressionInspector $ ValueExpressionType的PROPERTY转换为类java.lang.Boolean

时间:2015-07-03 14:32:09

标签: jsf bean-validation omnifaces

我在班级(http://showcase.omnifaces.org/validators/validateBean)与OmniFaces 1.11 <o: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>

TestBean.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处获得,只需运行清洁码头:run-war et go to http://localhost:14080/bo_ihm/testWithClassLevelValidation.xhtml

第二页http://localhost:14080/bo_ihm/testWithoutClassLevelValidation.xhtml是她证明课程级别约束不起作用,当我点击按钮时,我应该得到如下的验证错误消息:&#39; Pojo [forain] = false,cleSecuriteSociale = 22,numeroSecuriteSociale = 2531257351038,强制= null]无效&#39;

1 个答案:

答案 0 :(得分:1)

事实证明,隐含的EL强制导致了这一切。我们传递了内部值,如ValueExpressionType.PROPERTYValueExpressionType.METHOD,以指示EL表达式是表示属性(getter / setter)调用还是方法(操作)调用。但是,如果该值具有隐式EL强制支持(例如java.lang.Boolean),则该方法将失败,EL将隐式转换为例如"true"。字符串true到布尔值@using (MyApp.Models.ProjectsEntities db = new VodenjeDel.Models.ProjektiEntities()) { db.Configuration.LazyLoadingEnabled = false; var projects = db.projects; // no related data available db.Configuration.LazyLoadingEnabled = true; var projects = db.projects; // related data available }

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

根据this commit,OmniFaces 2.2已修复此问题。