1

我需要使用请求范围支持 bean 的相同变量,它是 h:selectOneListbox 和 h:selectManyListbox 的 List 数据类型。即使在使用转换器后,h:selectOneListbox 也会出现“ip:验证错误:值无效”错误。有人可以帮我解决这个问题吗?

在 page1.xhtml 我给它作为:

<h:selectManyListbox id="ip" value="#{inputBean.ipAddress}" size="5">
<f:selectItems value="#{inputBean.ipAddressList}" />
</h:selectManyListbox>

在 page2.xhtml 我给它作为:

<h:selectOneListbox id="ip" value="#{inputBean.ipAddress}" size="5">
    <f:selectItems value="#{inputBean.ipAddressList}" />
    <f:converter converterId="ipAddressConverter"></f:converter>
</h:selectOneListbox>

我的输入 bean,一个请求范围的托管 bean 如下所示:

@ManagedBean
@RequestScoped
public class InputTablePlot implements Serializable{
private static final long serialVersionUID = 1L;
@ManagedProperty("#{database}")
private Database database;
private Connection connection;
    private StringBuilder query;
    private PreparedStatement pst_query;
    private ResultSet rs;

private List<Long> ipAddress;
private Map<String, Long> ipAddrMenu;

public InputBean()
    {
        ipAddrMenu = new LinkedHashMap<String, Long>();
    }
@PostConstruct
    public void init()
    {
ipAddrMenu.clear();
try
        {
            connection = database.getDbConnection();
            query = new StringBuilder();
            query.append("SELECT distinct source AS ipaddr FROM addrtable ORDER BY source");
            pst_query = connection.prepareStatement(query.toString());
            rs = pst_query.executeQuery();
            while (rs.next())
            {
                ipAddrMenu.put(ipLongToString(rs.getLong("ipaddr")), rs.getLong("ipaddr")); // Adding
                // sources
            }
            rs.close();
            pst_query.close();
            connection.close();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
}
       public List<Long> getIpAddress()
    {
        System.out.println("In Getter" + ipAddress);
        return ipAddress;
    }

    public void setIpAddress(List<Long> ipAddress)
    {
        System.out.println("In Setter");
        System.out.println(ipAddress);
        this.ipAddress = ipAddress;

    }
        public Map<String, Long> getIpAddressList()
    {
        return ipAddrMenu;
    }

    public void setIpAddressList(Map<String, Long> ipAddressList)
    {
        this.ipAddrMenu = ipAddressList;
    }

@Override
    public int hashCode()
    {
final int prime = 31;
        int result = 1;
result = prime * result + ((connection == null) ? 0 : connection.hashCode());
        result = prime * result + ((database == null) ? 0 : database.hashCode());
        result = prime * result + ((ipAddrMenu == null) ? 0 : ipAddrMenu.hashCode());
        result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
return result;
}

@Override
    public boolean equals(Object obj)
    {
if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        InputBean other = (InputBean) obj;
if (connection == null)
        {
            if (other.connection != null)
                return false;
        }
        else if (!connection.equals(other.connection))
            return false;
        if (database == null)
        {
            if (other.database != null)
                return false;
        }
        else if (!m_database.equals(other.database))
            return false;
        if (ipAddrMenu == null)
        {
            if (other.ipAddrMenu != null)
                return false;
        }
        else if (!ipAddrMenu.equals(other.ipAddrMenu))
            return false;
        if (ipAddress == null)
        {
            if (other.ipAddress != null)
                return false;
        }
        else if (!ipAddress.equals(other.ipAddress))
            return false;

return true;
}

}

转换器代码:

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;


public class IpAddressConverter implements Converter
{

    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2)
    {
        List<Long> ipAddr = new ArrayList<Long>();
        try{
            ipAddr.add(Long.valueOf(arg2)); 
        }catch(NumberFormatException e){
            e.printStackTrace();
            FacesContext facesContext = FacesContext.getCurrentInstance();
            FacesMessage facesMessage = new FacesMessage("Problem with conversion of ip!");
            facesContext.addMessage(null, facesMessage);
        }
        for(int i=0; i< ipAddr.size(); i++){
            System.out.println("ipAddr >>> "+ipAddr);   
        }
        return ipAddr;
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2)
    {
        String val = null;
        try{
        Long ip = (Long) arg2;
        val = ip.toString();
        }catch(Exception e){
            e.printStackTrace();
            FacesContext facesContext = FacesContext.getCurrentInstance();
            FacesMessage facesMessage = new FacesMessage("Problem with conversion of ip!");
            facesContext.addMessage(null, facesMessage);
        }
        System.out.println("value >>> "+val);
        return val;
    }

}
4

1 回答 1

1

它失败是因为List<Long>转换器返回的与可用项目的单个项目不匹配,Long而 JSF 正在根据可用项目列表验证提交的(和转换的!)值(作为防止攻击者被篡改/欺骗的 HTTP 请求的一部分操纵选定的项目值)。转换器应该返回一个Long. 总而言之,这样的转换器根本不适合在UISelectOne组件中使用。

您最好将值直接绑定到单个属性。如果你坚持使用一个List属性,那么只需准备一个空项并在值中指定列表项索引。

private List<Long> ipAddress = new ArrayList<>(1);

<h:selectOneListbox id="ip" value="#{inputBean.ipAddress[0]}" size="5">
    <f:selectItems value="#{inputBean.ipAddressList}" />
</h:selectOneListbox>

也可以看看:

于 2013-07-22T17:08:49.500 回答