java JSF 验证错误:值无效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6324070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:22:43  来源:igfitidea点击:

JSF Validation Error: Value is not valid

javajsfjbossjboss6.xmojarra

提问by rich

I know this seems to be a common one, but I'm lost with it. Occurs on clicking the Add button in assessment.jsf. Anyway, I've attached what I think are the relevant sections.

我知道这似乎很常见,但我已经迷失了。在单击 Assessment.jsf 中的“添加”按钮时发生。无论如何,我已经附上了我认为相关的部分。

FWIW, AssessmentType.equals() isn't triggered when I debug.

FWIW,我调试时不会触发 AssessmentType.equals()。

Thanks in advance.

提前致谢。

j_idt38:j_idt47:j_idt48: Validation Error: Value is not valid

assessment.xhtml:

评估.xhtml:

        <h:form>
            <h:selectOneMenu value="#{assessmentBean.assessmentField}">
                <f:selectItems value="#{assessmentBean.assessment.type.fields}" />
            </h:selectOneMenu>

            <h:commandButton value="Add" action="#{assessmentBean.doAddField}">
                <f:param name="assessmentId"
                    value="#{assessmentBean.assessment.id}" />
            </h:commandButton>
        </h:form>

assessment.jsf:

评估.jsf:

<form id="j_idt38:j_idt47" name="j_idt38:j_idt47" method="post" action="/jsf-web/edit/assessment.jsf" enctype="application/x-www-form-urlencoded"> 
<input type="hidden" name="j_idt38:j_idt47" value="j_idt38:j_idt47" /> 
<select name="j_idt38:j_idt47:j_idt48" size="1">    <option value="1">Presenting Condition</option> 
    <option value="2">Problem Duration</option> 
</select> 
<script type="text/javascript" src="/jsf-web/javax.faces.resource/jsf.js.jsf?ln=javax.faces"></script>
<input type="submit" name="j_idt38:j_idt47:j_idt50" value="Add" onclick="mojarra.jsfcljs(document.getElementById('j_idt38:j_idt47'),{'j_idt38:j_idt47:j_idt50':'j_idt38:j_idt47:j_idt50','assessmentId':'1'},'');return false" /><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="3431661972220941645:6952134510589038883" autocomplete="off" /> 
</form> 

AssessmentType.java:

评估类型.java:

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotNull;

import lombok.Data;

import org.hibernate.envers.Audited;

@Audited
@Data
@Entity
public class AssessmentType implements Comparable<AssessmentType> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String name;

    @OneToMany( fetch=FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, targetEntity=AssessmentField.class )
    private List<AssessmentField> fields;

    @Override
    public int compareTo(final AssessmentType o) {
        return getId().compareTo(o.getId());
    }

    @Override
    public String toString() {
        return getName();
    }
}

AssessmentFieldConverter.java

评估字段转换器.java

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.htu.fizio.api.AssessmentFieldManager;
import com.htu.fizio.domain.AssessmentField;

@FacesConverter(forClass = AssessmentField.class)
public class AssessmentFieldConverter implements Converter {

    AssessmentFieldManager<AssessmentField> assessmentFieldManager;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
        try {
            final InitialContext ic = new InitialContext();

            assessmentFieldManager = (AssessmentFieldManager) ic.lookup("fizio/AssessmentFieldManagerImpl/local");

            return assessmentFieldManager.find(Long.valueOf(value));
        } catch (NamingException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public String getAsString(FacesContext ctx, UIComponent component, Object value) {
        return String.valueOf(((AssessmentField) value).getId());
    }
}

AssessmentBean.java

评估Bean.java

    import java.util.List;

    import javax.annotation.PostConstruct;
    import javax.ejb.EJB;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ManagedProperty;
    import javax.faces.bean.SessionScoped;

    import lombok.Getter;
    import lombok.Setter;

    import com.htu.fizio.api.AssessmentManager;
    import com.htu.fizio.domain.Assessment;
    import com.htu.fizio.domain.AssessmentField;
    import com.htu.fizio.domain.AssessmentFieldValue;
    import com.htu.fizio.jsf.faces.FacesUtil;

...    

@PostConstruct
public void init() {
    if (FacesUtil.containsKey("assessmentId")) {
        final Long id = Long.parseLong(FacesUtil.get("assessmentId"));

        assessment = assessmentManager.find(id);
    } else {
        assessment = new Assessment();
    }
}

    public String doAddField() {
        final AssessmentFieldValue value = new AssessmentFieldValue();

        value.setField(assessmentField);
        value.setValue("");

        assessment.getFieldValues().add(value);

        assessmentManager.save(assessment);

        return "/edit/assessment";
    }

Edit:

编辑:

Just noticed this when debugging, is it a likely suspect?:

刚刚在调试时注意到这一点,它可能是一个嫌疑人吗?:

Daemon Thread [HandshakeCompletedNotify-Thread] (Suspended (exception ConcurrentModificationException)) 
    HashMap$EntryIterator(HashMap$HashIterator<E>).nextEntry() line: 793    
    HashMap$EntryIterator.next() line: 834  
    HashMap$EntryIterator.next() line: 832  
    SSLSocketImpl$NotifyHandshakeThread.run() line: 2214    

采纳答案by rich

I think I've resolved this, at least, I've moved on to the next error!

我想我已经解决了这个问题,至少,我已经转向了下一个错误!

Despite posting reams of code I'd not posted the full xhtml in which there were multiple and nested form tags. Just the one form seems to allow passing the assessmentId parameter which in turn allows the AssessmentBean to then populate the List of AssessmentFields for the assessment type correctly.

尽管发布了大量代码,但我没有发布完整的 xhtml,其中有多个嵌套的表单标签。只有一种形式似乎允许传递 AssessmentId 参数,这反过来又允许 AssessmentBean 正确填充评估类型的 AssessmentFields 列表。

Thanks for all the help.

感谢所有的帮助。

回答by BalusC

Validation Error: Value is not valid

验证错误:值无效

To the point, this error means that the selected item does not match any of the items available in the list. I.e. the object represented by the selected item value has never returned trueon its equals()call with any of the available select items.

就此而言,此错误意味着所选项目与列表中的任何可用项目都不匹配。即由所选项目值表示的对象trueequals()调用任何可用选择项目时从未返回。

There are only two causes for this problem:

这个问题只有两个原因:

  1. The equals()method of the object type in question is broken.
  2. The contents of the list of items is different during the validations phase of the form submit request than as it was during the render response phase of the initial request to display the form.
  1. equals()问题的对象类型的方法已损坏。
  2. 项目列表的内容在表单提交请求的验证阶段与在显示表单的初始请求的呈现响应阶段不同。

Since the first seems to be properly implemented -as per the comments-, the only cause left is the second. Assuming that you're nowhere doing business logic in a getter method, an easy test is to put the #{assessmentBean}in the session scope. If it works, then the data (pre)loading logic of the list of select items is definitely wrong.

由于第一个似乎得到了正确实施 - 根据评论 - 剩下的唯一原因是第二个。假设您没有在 getter 方法中处理业务逻辑,一个简单的测试是将 放在#{assessmentBean}会话范围内。如果它有效,那么选择项列表的数据(预)加载逻辑肯定是错误的。

回答by Arjan Tijms

The validation is failing because after your converter converts the String representation of AssessmentType back to an object, JSF iterates over the existing values (assessmentBean.assessment.type.fields) and compares this recently converted object with all those existing ones.

验证失败,因为在您的转换器将 AssessmentType 的 String 表示形式转换回对象后,JSF 迭代现有值 ( assessmentBean.assessment.type.fields) 并将这个最近转换的对象与所有这些现有值进行比较。

Since you did not implement Object#equalsfor AssessmentType, it will default to an object identity comparison (roughly spoken, the memory address of your object) , which will of course fail.

由于您没有实现Object#equalsAssessmentType,它将默认为对象标识比较(粗略地说,您的对象的内存地址),这当然会失败。

The solution is thus to either implement Object#equals, or let the converter get the object from assessmentBean.assessment.type.fieldsinstead of from AssessmentTypeManager.

因此,解决方案是要么实现Object#equals,要么让转换器从 fromassessmentBean.assessment.type.fields而不是 from获取对象AssessmentTypeManager