问题
I have this SelectOneMenu:
<h:selectOneMenu value="#{orderController.requestVO.requestSituation}">
<f:converter converterId="ComboConverter"/>
<f:selectItems value="#{orderController.requestSituation}" var="requestSituation"
itemLabel="#{requestSituation.description}" itemValue="#{requestSituation}" />
</h:selectOneMenu>
The requestSituation
is a ArrayList
filled with RequestSituationVO
It is populated correctly, generating this HTML:
<select name="j_idt14:j_idt20" size="1">
<option value="13">Pedido Recusado</option>
<option value="11">Pedido Validado</option>
<option value="12" selected="selected">Pedido Confirmado</option>
<option value="12" selected="selected">Pedido Faturado</option>
</select>
I have this Converter
and here is where I'm confused, I've read a lot and I know what it has to do but not how it works.
Here it is:
@FacesConverter(value = "ComboConverter", forClass = RequestSituationVO.class)
public class ComboConverter implements Converter
{
private static RequestSituationVO requestSituationVO = new RequestSituationVO();
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
requestSituationVO.setId(Integer.valueOf(value));
requestSituationVO = (RequestSituationVO) new RequestSituationBO().getRequestSituation(requestSituationVO).toArray()[0];
return (RequestSituationVO) requestSituationVO;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
requestSituationVO = (RequestSituationVO) value;
String teste = String.valueOf(requestSituationVO.getId());
return teste;
}
}
When I submit my page, I think the SelectOneMenu
will automatically set the value for the requestSituation
method from requestVO
. But when I submit, I get a message Value not valid
referencing to my SelectOneMenu
.
What I need is to set the selected value on my RequestSituationVO
so I can send it to the Business method.
回答1:
Your converter is fine. You would otherwise have gotten a conversion error something like
Conversion Error setting value 'com.example.RequestSituationVO@hashcode' for 'null Converter'
You've a validation error. This particular one will be thrown when the Object#equals() test of the selected item hasn't returned true
for any of the available items in the list. JSF is checking that to prevent attacks by tampered requests. This can in your particular case have the following causes:
- The
equals()
method of theRequestSituationVO
class is missing or broken. - The
#{orderController.requestSituation}
has incompatibly changed in between the request of displaying the form and the request of processing the form submit.
I think that it's the former. Given the fact that your RequestSituationVO
has an Integer id
property which uniquely identifies the object, this should do:
@Override
public boolean equals(Object other) {
return (other instanceof RequestSituationVO) && (id != null)
? id.equals(((RequestSituationVO) other).id)
: (other == this);
}
@Override
public int hashCode() {
return (id != null)
? (this.getClass().hashCode() + id.hashCode())
: super.hashCode();
}
If the equals()
method is not the problem, then it's the latter cause. This can be solved by making sure that the #{orderController.requestSituation}
returns exactly the same list during displaying the form and processing the form submit. This can be achieved by placing the bean in the view scope and not doing the business logic in the getter at all. Or if it actually represents applicationwide data, you could refactor it to a separate application scoped bean.
See also
- Our selectOneMenu wiki page
回答2:
It looks like you forgot to implement equals
and hashCode
in RequestSituation
.
This is very important, as JSF will compare the submitted value against all the given items.
If you don't implement equals
, it thinks the submitted item is not in the list,
so it rejects it. (The value is not valid.
)
来源:https://stackoverflow.com/questions/10605468/using-jsf-converter-in-hselectonemenu-results-in-validation-error-value-not-va