如何在 JSF 中创建选择列表?尝试使用 JS/jQuery 移动项目,但使用“验证错误:值无效”提交错误

Posted

技术标签:

【中文标题】如何在 JSF 中创建选择列表?尝试使用 JS/jQuery 移动项目,但使用“验证错误:值无效”提交错误【英文标题】:How to create a picklist in JSF? Tried moving items using JS/jQuery, but submit errors with "Validation Error: Value is not valid" 【发布时间】:2012-10-04 04:10:17 【问题描述】:

我正在使用 JSF 2.0 创建 Web 应用程序,并在其中分配用户查看项目。为此,我有两个清单。第一个列表包含未分配该项目的用户,列表 B 包含已分配该项目的用户。我们可以交换数据。

我的代码是


<t:selectManyListbox id="sourceCars"  style="width: 40%;"
                     value="#PersonalInformationDataBean.listOfUsers" size="10">
    <t:selectItems value="#PersonalInformationDataBean.showAllMyRemData()" var="t"
                   itemLabel="#t.title" itemValue="#t.status"/>
</t:selectManyListbox>

<span>
    <input type="button" value=" >> " id="dbleMeRight"/>
    <input type="button" value=" &lt;&lt; " id="dbleMeLeft"/>
</span>

<t:selectManyListbox id="targetCars"  style="width: 40%;"
                     value="#PersonalInformationDataBean.listOfUsers" size="10">
    <t:selectItems value="#PersonalInformationDataBean.showAllMyData()" var="n"
                   itemLabel="#n.title" itemValue="#n.status"/>
</t:selectManyListbox>

<h:commandButton value="Save Edited Project Info." action="#PersonalInformationDataBean.editPatentData(MyLogin.loginname)" />

其中 t 是 xmlns:t="http://myfaces.apache.org/tomahawk"


PersonalInformationDataBean.java

private List<String> listOfUsers = new ArrayList<String>();
private List<String> listOfUsers002 = new ArrayList<String>();
private List<CommonBean01> listOfListUsers = new ArrayList<CommonBean01>();
private List<CommonBean01> listOfListUsers002 = new ArrayList<CommonBean01>();

// above getter and setters

Iterator itr = listOfUsers.iterator();
System.out.println("list of usersssss == " + listOfUsers);

while (itr.hasNext()) 
    psmtt = conn.prepareStatement("INSERT INTO patentInvite (invitedWhom, patentId, personalInfoId) VALUES (?,?,?)");
    String inviteWhom = itr.next().toString();
    System.out.println("to who we have invited is " + inviteWhom);
    psmtt.setString(1, inviteWhom);
    psmtt.setLong(2, patentId);
    psmtt.setLong(3, personalInfoId);
    psmtt.execute();

    System.out.println("Data entered is == " + inviteWhom + "==" + patentId + "==" + personalInfoId + "==");


public List<CommonBean01> showAllMyRemData() 
    try 
        CommonBean01 commonBean = new CommonBean01();
        listOfListUsers = new ArrayList<CommonBean01>();
        ConnectToDatabase db = new ConnectToDatabase();
        Connection conn = db.makeconnection();


        PreparedStatement psmt = conn.prepareStatement("SELECT * FROM patentInvite WHERE patentId=?");
        System.out.println("patent id here is " + patentId);
        psmt.setLong(1, patentId);
        ResultSet rs = psmt.executeQuery(), rs2 = null;
        PreparedStatement pstt = null;

        int dd = 0;
        String listOfUser = "";
        int myCounter = 0;
        while (rs.next()) 
            if (myCounter==0) 
                listOfUser = "'" + rs.getString(2) + "'"; 
             else 
                listOfUser = listOfUser + ",'" + rs.getString(2) + "'";
            
            myCounter++;
        

        System.out.println("id selected are :: " + listOfUser);

        psmt = conn.prepareStatement("SELECT userid, fullName, userType FROM userDetails WHERE userid NOT IN (" + listOfUser + ")");
        rs = psmt.executeQuery();

        listOfListUsers = new ArrayList<CommonBean01>();
        while (rs.next()) 
            commonBean = new CommonBean01();
            commonBean.setStatus(rs.getString(1));
            commonBean.setTitle(rs.getString(2) + " [" + rs.getString(3) + "]");
            listOfListUsers.add(commonBean);
            System.out.println("wat say....(" + rs.getString(1) + ") -- " + rs.getString(2) + "");
        
        return listOfListUsers;
     catch (Exception e) 
        System.out.println("Exception = " + e);
        return null;
    


public List<CommonBean01> showAllMyData() 
    try 
        CommonBean01 commonBean = new CommonBean01();
        listOfListUsers = new ArrayList<CommonBean01>();
        ConnectToDatabase db = new ConnectToDatabase();
        Connection conn = db.makeconnection();

        PreparedStatement psmt = conn.prepareStatement("SELECT * FROM patentInvite WHERE patentId=?");
        System.out.println("patent id here is " + patentId);
        psmt.setLong(1, patentId);
        ResultSet rs = psmt.executeQuery(), rs2 = null;
        PreparedStatement pstt = null;
        listOfListUsers = new ArrayList<CommonBean01>();

        while (rs.next()) 
            System.out.println("");
            pstt = conn.prepareStatement("SELECT userid, fullName, userType FROM userDetails WHERE userid=?");
            pstt.setString(1, rs.getString(2));
            System.out.println("setting id for " + rs.getString(1));
            rs2 = pstt.executeQuery();

            int dd = 0;
            while (rs2.next()) 
                System.out.println("inside data " + rs2.getString(2));
                commonBean = new CommonBean01();
                commonBean.setStatus(rs2.getString(1));
                commonBean.setTitle(rs2.getString(2) + " [" + rs2.getString(3) + "]");
                listOfListUsers.add(commonBean);
                System.out.println("wat say here....(" + rs2.getString(1) + ") -- " + rs2.getString(2) + "");
            
        
        return listOfListUsers;
     catch (Exception e) 
        System.out.println("Exception = " + e);
        return null;
    


CommonBean01.java

public class CommonBean01 
    private String title;
    private String status;

    public String getStatus() 
        return status;
    

    public void setStatus(String status) 
        this.status = status;
    

    public String getTitle() 
        return title;
    

    public void setTitle(String title) 
        this.title = title;
    

    @Override
    public boolean equals(Object obj) 
        if (obj == null) 
            return false;
        
        if (getClass() != obj.getClass()) 
            return false;
        
        final CommonBean01 other = (CommonBean01) obj;
        if ((this.status == null) ? (other.status != null) : !this.status.equals(other.status)) 
            return false;
        
        return true;
    

    @Override
    public int hashCode() 
        int hash = 5;
        hash = 89 * hash + (this.status != null ? this.status.hashCode() : 0);
        return hash;
    


现在,当我将用户从左侧列表带到右侧列表并单击 Save Edit Info 按钮时,我收到错误为 targetCars: Validation Error: Value is not valid

注意:

当我不更改任何列表并单击Save Edit Info时,它运行良好。

知道为什么我会收到此错误吗?


编辑 1

我做了以下改动

<t:selectManyListbox id="sourceCars"  style="width: 40%;"
                     value="#PersonalInformationDataBean.listOfUsers002" size="10">
    <t:selectItems value="#PersonalInformationDataBean.showAllMyRemData()" var="t"
                   itemLabel="#t.title" itemValue="#t.status"/>
</t:selectManyListbox>


public List<CommonBean01> showAllMyRemData() 
    try 
        CommonBean01 commonBean = new CommonBean01();
        listOfListUsers002 = new ArrayList<CommonBean01>();
        ConnectToDatabase db = new ConnectToDatabase();
        Connection conn = db.makeconnection();


        PreparedStatement psmt = conn.prepareStatement("SELECT * FROM patentInvite WHERE patentId=?");
        System.out.println("patent id here is " + patentId);
        psmt.setLong(1, patentId);
        ResultSet rs = psmt.executeQuery(), rs2 = null;
        PreparedStatement pstt = null;

        int dd = 0;
        String listOfUser = "";
        int myCounter = 0;
        while (rs.next()) 
            if (myCounter==0) 
                listOfUser = "'" + rs.getString(2) + "'"; 
             else 
                listOfUser = listOfUser + ",'" + rs.getString(2) + "'";
            
            myCounter++;
        

        System.out.println("id selected are :: " + listOfUser);

        psmt = conn.prepareStatement("SELECT userid, fullName, userType FROM userDetails WHERE userid NOT IN (" + listOfUser + ")");
        rs = psmt.executeQuery();

        listOfListUsers002 = new ArrayList<CommonBean01>();
        while (rs.next()) 
            commonBean = new CommonBean01();
            commonBean.setStatus(rs.getString(1));
            commonBean.setTitle(rs.getString(2) + " [" + rs.getString(3) + "]");
            listOfListUsers002.add(commonBean);
            System.out.println("wat say....(" + rs.getString(1) + ") -- " + rs.getString(2) + "");
        
        return listOfListUsers002;
     catch (Exception e) 
        System.out.println("Exception = " + e);
        return null;
    

我仍然遇到同样的错误。


编辑 2

移动项目的jQuery代码如下。

$(function() 
    var  sourceCars=$('#sourceCars option').clone();
    $('#filterDis').change(function() 
        var val = $(this).val();
        alert("changed me=="+val+"==");
        $('#sourceCars').empty();
        alert("changed me=="+sourceCars+"==");
        sourceCars.filter(function(idx, el) 
            var found=false;
            $('#targetCars option').each(function()
                if ($(this).val()===$(el).text())
                    found=true;
            );
            alert(found);

            if(found)
                return false;

            return val === 'ALL' || $(el).text().indexOf('[' + val + ']') >= 0;
        ).appendTo('#sourceCars');
        $("#targetCars option").attr("selected", "selected");
    );

    $('#sourceCars').dblclick(function() 
        $('#sourceCars option:selected').appendTo('#targetCars');
        $("#targetCars option").attr("selected", "selected");
    );

    $('#dbleMeRight').click(function() 
        $('#sourceCars option:selected').appendTo('#targetCars');
        $("#targetCars option").attr("selected", "selected");
    );

    $('#targetCars').dblclick(function() 

        var targetList=$('#targetCars option:selected');
        var filterVal= $('#filterDis').val();
        if( filterVal === 'ALL' || targetList.text().indexOf('[' + filterVal + ']') >= 0)
            targetList.appendTo('#sourceCars');
        else
            targetList.remove();
        var foption = $('#sourceCars option:first');
        var soptions = $.makeArray($('#sourceCars option:not(:first)')).sort(function(a, b) 
            return a.text == b.text ? 0 : a.text &lt; b.text ? -1 : 1
        );
        $('#sourceCars').html(soptions).prepend(foption);
        foption.attr("selected", true).siblings("option").removeAttr("selected");
        $("#targetCars option").attr("selected", "selected");
    );

    $('#dbleMeLeft').click(function() 

        var targetList=$('#targetCars option:selected');
        var filterVal= $('#filterDis').val();
        if( filterVal === 'ALL' || targetList.text().indexOf('[' + filterVal + ']') >= 0)
            targetList.appendTo('#sourceCars');
        else
            targetList.remove();
        var foption = $('#sourceCars option:first');
        var soptions = $.makeArray($('#sourceCars option:not(:first)')).sort(function(a, b) 
            return a.text == b.text ? 0 : a.text &lt; b.text ? -1 : 1
        );
        $('#sourceCars').html(soptions).prepend(foption);
        foption.attr("selected", true).siblings("option").removeAttr("selected");
        $("#targetCars option").attr("selected", "selected");
    );

);

注意:如果我将项目从列表 B(右)移动到列表 A(左),它工作正常。但是当我将项目从列表 A(左)移动到列表 B(右)时,我收到了这个错误。


【问题讨论】:

点击左/右键时你写了什么代码?问题似乎在那里,将那段代码粘贴到此处以帮助您。 那是一个 jquery 代码。我将粘贴相同的内容...我认为这不是问题,就像我从列表 B 删除到 A 一样它可以工作。但是,如果我将任何项目从 A 放到 B,我会得到错误 @sudmong : 我已经添加了代码... 您遇到了转换错误。在 JSF 中,当您使用自定义对象列表来填充任何 selecItem 类型的 UI 组件时,您需要实现自定义 converter,这将有助于 JSF 理解提交。我希望我能提供更多帮助,但事实上,您的代码很难阅读。与问题无关,请为您的变量尝试替代命名约定。很难理解tttttt2 之类的东西。转换器教程here。对于原始/标准 java 类型,不需要。 @kolossus :我现在对代码进行了更改...请让我知道更改。 【参考方案1】:

直截了当,您的具体问题是由于您使用 javascript/jQuery 而不是 JSF 填充列表框项的错误造成的。这样,JSF 就不会知道 JavaScript 添加的新项目。您需要使用 JSF 而不是 JavaScript/jQuery 来填充列表框项。

当您提交带有UISelectOne/UISelectMany 组件的表单时,JSF 将始终将提交的值与来自&lt;f:selectItem(s)&gt; 的可用项目列表进行比较。如果提交的值不包含在可用项目列表中,那么您将得到这个Validation Error: Value is not valid 错误。这是针对被篡改/攻击请求的内置保护措施的一部分。客户端应该无法提交服务器未指定的项目。

更改 JavaScript/jQuery 端的可用项目也会自动更改 JSF &lt;f:selectItems&gt; 端的可用项目。您确实需要更改 JSF 端的可用项目。您可以轻松地为此使用 JSF 2.x ajax 功能。这是一个具体的启动示例:

<h:form>
    <h:panelGrid columns="3">
        <h:selectManyListbox id="left" value="#bean.leftSelected">
            <f:selectItems value="#bean.leftAvailable" />
            <f:ajax event="dblclick" render="left right" listener="#bean.leftToRight" />
        </h:selectManyListbox>
        <h:panelGroup>
            <h:commandButton value="left to right">
                <f:ajax execute="left" render="left right" listener="#bean.leftToRight" />
            </h:commandButton>
            <br/>
            <h:commandButton value="right to left">
                <f:ajax execute="right" render="left right" listener="#bean.rightToLeft" />
            </h:commandButton>
        </h:panelGroup>
        <h:selectManyListbox id="right" value="#bean.rightSelected">
            <f:selectItems value="#bean.rightAvailable" />
            <f:ajax event="dblclick" render="left right" listener="#bean.rightToLeft" />
        </h:selectManyListbox>
    </h:panelGrid>
</h:form>

@Named
@ViewScoped
public class Bean 

    private List<String> leftSelected;
    private List<String> leftAvailable;
    private List<String> rightSelected;
    private List<String> rightAvailable;

    @PostConstruct
    public void init() 
        leftAvailable = new ArrayList<String>(Arrays.asList("one", "two", "three", "four", "five"));
        rightAvailable = new ArrayList<String>();
    

    public void leftToRight() 
        leftAvailable.removeAll(leftSelected);
        rightAvailable.addAll(leftSelected);
        leftSelected = null;
    

    public void rightToLeft() 
        rightAvailable.removeAll(rightSelected);
        leftAvailable.addAll(rightSelected);
        rightSelected = null;
    

    // Add/generate getters+setters. Note: the "available" lists doesn't need setters.

就是这样。不需要 JS/jQuery 混乱。使用自定义非字符串对象时不要忘记提供适当的转换器和equals() 方法。

另见:

What is the need of JSF, when UI can be achieved with JavaScript libraries such as jQuery and AngularJS Validation Error: Value is not valid Conversion Error setting value for 'null Converter' - Why do I need a Converter in JSF?

【讨论】:

我在列表中有对象...所以我添加了&lt;f:selectItems value="#PersonalInformationDataBean.listOfListUsers002" var="leftSide" itemLabel="#leftSide.title" itemValue="#leftSide"/&gt;。所有数组列表类型为private List&lt;CommonBean02&gt; listOfUsers = new ArrayList&lt;CommonBean02&gt;();。当我尝试移动时,它会弹出serverError: class java.lang.ClassCastException java.lang.String cannot be cast to com.sac.beans.CommonBean02 您的转换器丢失或损坏。这个问题与具体问题无关。答案中的代码按原样工作。例如,请在此处查看:***.com/questions/4734580/… 关于这个我明天要工作,因为必须完成另一个项目的一些事情......明天如果有任何问题会回复你...... 你能看看我的新question

以上是关于如何在 JSF 中创建选择列表?尝试使用 JS/jQuery 移动项目,但使用“验证错误:值无效”提交错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSF EL 中创建一个数组?

如何在 KivyMD 中创建选择列表

如何在 JSF 中执行验证,如何在 JSF 中创建自定义验证器

如何在 JSF 中创建现有组件的组合?

如何在JSF中创建可重用的组件?

如何在 JSF 2.0 中创建自定义 404 消息?