验证错误值无效 [英] Validation error value is not valid
问题描述
我知道这是一个常见错误,对此有很多疑问,但是我必须创建一个新的错误.
I know this is a common error, and that there is a lots of questions about it, but I must create new one.
这是我的jsf页面:
<h:form id="clientCreatingForm">
<p:selectOneMenu id="city" value="#{kkmBean.client.address.city}" style="width: 263px;"
converter="cityConveter" required="true" requiredMessage="You must choose one city">
<f:selectItems value="#{kkmBean.cityList}" var="city" itemLabel="#{city.cityName}" itemValue="#{city.cityID}"/>
</p:selectOneMenu>
<p:commandButton value="Save client" type="button" onclick="confirm.show()" style="margin-top: 20px; margin-left: 30px; width: 180px;" />
<p:commandButton value="Reset fields" type="reset" style="margin-top: 20px; margin-left: 30px; width: 180px;"/>
<p:confirmDialog message="Are you sure, you want to save client?"
header="Save client" severity="info" widgetVar="confirm">
<p:commandButton value="Yes, I am sure." oncomplete="confirm.hide()"
action="#{kkmBean.saveClient}" update=":warnings" style="font-size: 12px;"/>
<p:commandButton value="No, I don't!" onclick="confirm.hide()" type="button" style="font-size: 12px;"/>
</p:confirmDialog>
</h:form>
这里是托管bean:
@ManagedBean(name = "kkmBean")
@SessionScoped
public class CreatingClientManager implements Serializable {
/** Creates a new instance of CreatingClientManager */
public KreiranjeKorisnikaManager() {
client= new Client();
client.setAddress(new Address());
cityList = new LinkedList<City>();
cityList = Communication.getInstance().getCitySessionBeanRemote().getCities();
}
private Client client;
private List<City> cityList;
public String startCreatingClent() {
return "creating-client";
}
/**
* @return the client
*/
public Klijent getClient() {
return client;
}
/**
* @param client the client to set
*/
public void setClient(Client client) {
this.Client = client;
}
/**
* @return the cityList
*/
public List<Grad> getCityList() {
return cityList;
}
/**
* @param cityList the cityList to set
*/
public void setCityList(List<City> cityList) {
this.cityList = cityList;
}
public String saveClient() {
System.out.println("i am in saveClient method");
String message = Communication.getInstance().getClientSessionBeanRemote.saveClient(client);
FacesContext context = FacesContext.getCurrentInstance();
kontekst.addMessage(message, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success: ", message));
return null;
}
}
最后是转换器:
@FacesConverter(forClass=City.class, value="cityConverter")
public class CityConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Integer cityID = Integer.valueOf(value);
CreatingClientManager kkm = (CreatingClientManager) ((HttpSession)context.getExternalContext().getSession(true)).getAttribute("kkmBean");
List<Grad> cityList = kkm.getCityList();
for (int i = 0; i < cityList.size(); i++) {
City city = cityList.get(i);
if(city.getCityID().equals(cityID)) {
System.out.println(city.getCityName());
return city;
}
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value.toString();
}
}
当然,问题出在selectOneMenu中.提交表单时,出现了这个令人讨厌的错误.
Of course the problem is in selectOneMenu. When I submit form, i got this annoying error.
我正在调试转换器,返回grad之前的行,我打印grad.getImeGrada(),一切都很好,打印出找到的城市(grad)的名称(Ime).我想念什么吗?
I was debugging converter and the line before return grad, i print grad.getImeGrada() and everything is fine, the name (Ime) of found city (grad) is printed. Am I missing something?
p.s.对不起,我的英文,希望您能理解我的问题.
p.s. Sorry on my English, I hope that you understand what is my problem.
几乎忘了提到我重写了equals和hashCode方法,并且我确定它是可以的.
Almost forgot to mention that i override equals and hashCode methods, and i am sure it is ok.
推荐答案
指定<f:selectItems>
的itemValue
和实现转换器的getAsString()
的方式不正确.
The way how you specified the itemValue
of <f:selectItems>
and implemented the getAsString()
of the converter is not right.
提交选定的值后,JSF将通过转换器的getAsObject()
将cityID
转换为City
.然后,JSF将对照<f:selectItems>
的itemValue
验证City
,以查看它是否确实是列表的一部分(这是为了避免黑客修改/篡改具有不同值的请求).但是,由于itemValue
是cityID
(它是Integer
),因此对于列表的每个项目,比较都会失败.因此,出现Value not valid
错误.
When the selected value is submitted, JSF will convert the cityID
to City
by getAsObject()
of the converter. Then, JSF will validate the City
against the itemValue
of the <f:selectItems>
to see if it is really part of the list (this is to avoid hackers which modifies/tampers requests with a different value). However, since itemValue
is cityID
which is an Integer
the comparison fails for every item of the list. Hence the Value not valid
error.
您需要将itemValue
更改为City
,然后将getAsString()
更改为返回cityID
:
You need to change itemValue
to be City
instead and change getAsString()
to return the cityID
:
<p:selectOneMenu id="city" value="#{kkmBean.client.address.city}" style="width: 263px;"
converter="cityConveter" required="true" requiredMessage="You must choose one city">
<f:selectItems value="#{kkmBean.cityList}" var="city" itemLabel="#{city.cityName}" itemValue="#{city}"/>
</p:selectOneMenu>
和
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
City city = (City) value;
return city.getCityID() != null ? String.valueOf(city.getCityID()) : null;
}
总结:itemValue
的类型必须与下拉菜单value
完全相同,并且转换器必须在该类型和字符串之间进行转换.
Summarized: the type of the itemValue
must be exactly the same as the type of the dropdown value
and the converter must convert between exactly that type and string.
这篇关于验证错误值无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!