验证错误值无效 [英] Validation error value is not valid

查看:91
本文介绍了验证错误值无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这是一个常见错误,对此有很多疑问,但是我必须创建一个新的错误.

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,以查看它是否确实是列表的一部分(这是为了避免黑客修改/篡改具有不同值的请求).但是,由于itemValuecityID(它是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆