validation - definir - Error de validación: el valor no es válido
error de conversión al definir el valor (2)
La validación falla con el mensaje "formulario: ubicación: Error de validación: el valor no es válido"
Este error se reduce a que el elemento seleccionado no coincide con ninguno de los valores de elementos seleccionados disponibles especificados por cualquier etiqueta anidada <f:selectItem(s)>
durante el procesamiento de la solicitud de envío del formulario.
Como parte de la protección contra las solicitudes manipuladas / pirateadas, JSF reiterará todos los valores de elementos seleccionados disponibles y probará si selectedItem.equals(availableItem)
devuelve true
para al menos un valor de artículo disponible. Si no coincide el valor de un elemento, obtendrá exactamente este error de validación.
Este proceso está bajo las cubiertas básicamente como abajo, donde bean.getAvailableItems()
representa ficticiamente la lista completa de elementos selectos disponibles según lo definido por <f:selectItem(s)>
:
String submittedValue = request.getParameter(component.getClientId());
Converter converter = component.getConverter();
Object selectedItem = (converter != null) ? converter.getAsObject(context, component, submittedValue) : submittedValue;
boolean valid = false;
for (Object availableItem : bean.getAvailableItems()) {
if (selectedItem.equals(availableItem)) {
valid = true;
break;
}
}
if (!valid) {
throw new ValidatorException("Validation Error: Value is not valid");
}
Entonces, basado en la lógica anterior, este problema lógicamente puede tener al menos las siguientes causas:
- El elemento seleccionado falta en la lista de elementos disponibles.
- El método
equals()
de la clase que representa el elemento seleccionado falta o está roto. - Si se trata de un
Converter
personalizado, ha devuelto el objeto incorrecto engetAsObject()
. Quizás es inclusonull
.
Para resolverlo:
- Asegúrese de que se conserva exactamente la misma lista durante la solicitud posterior, especialmente en el caso de múltiples menús en cascada. Hacer que Bean
@ViewScoped
lugar de@RequestScoped
lo arregle en la mayoría de los casos. También asegúrese de no realizar la lógica de negocios en el método getter de<f:selectItem(s)>
, sino en el@PostConstruct
o un evento de acción (oyente). Si confía en parámetros de solicitud específicos, deberá almacenarlos explícitamente en el bean@ViewScoped
, o volver a pasarlos a solicitudes posteriores, por ejemplo,<f:param>
. Consulte también ¿Cómo elegir el alcance del frijol correcto? - Asegúrese de que el método
equals()
se implemente correctamente. Esto ya se hace correctamente en tipos Java estándar comojava.lang.String
,java.lang.Number
, etc., pero no necesariamente en objetos personalizados / beans / entites. Ver también La forma correcta de implementar es igual a contrato . En caso de que ya esté utilizandoString
, asegúrese de que la codificación de caracteres de la solicitud esté configurada correctamente. Si contiene caracteres especiales y JSF está configurado para representar la salida como UTF-8 pero interpreta la entrada como, por ejemplo, ISO-8859-1, fallará. Consulte también si la entrada Unicode recuperada a través de los componentes de entrada PrimeFaces se daña . - Depure / registre las acciones de su
Converter
personalizado y corríjalo según corresponda. Para obtener instrucciones, consulte también Valor de configuración de error de conversión para ''convertidor nulo'' En caso de que esté utilizandojava.util.Date
como elementos disponibles con<f:convertDateTime>
, asegúrese de no olvidar la parte de tiempo completo en el patrón . Consulte también el error "Error de validación: el valor no es válido" de f: datetimeConverter .
Ver también:
- Nuestra página wiki
selectOneMenu
- Cómo llenar las opciones de h: selectOneMenu de la base de datos?
- Hacer múltiples listas desplegables selectOneMenu dependientes / en cascada en JSF
Si alguien puede arrojar algunos consejos para la solución de problemas / depuración para este tipo de problema, sería muy apreciado.
Simplemente haga una pregunta clara y concreta aquí. No haga preguntas demasiado amplias;)
Tengo un problema con ap: selectOneMenu, no importa lo que haga, no puedo hacer que JSF llame al setter en la entidad JPA. La validación de JSF falla con este mensaje:
formulario: ubicación: Error de validación: el valor no es válido
Tengo esto trabajando en varias otras clases del mismo tipo (es decir, unirme a las clases de tabla) pero no puedo por mi vida hacer que funcione.
Si alguien puede arrojar algunos consejos para la solución de problemas / depuración para este tipo de problema, sería muy apreciado.
Usando declaraciones de registro, he verificado lo siguiente:
- El
Conveter
está devolviendo valores correctos, nonull
. - No tengo Validación de frijol en mis entidades JPA.
- El conjunto
setLocation(Location location)
nunca se llama.
Este es el ejemplo más simple que puedo hacer y simplemente no funcionará:
<h:body>
<h:form id="form">
<p:messages id="messages" autoUpdate="true" />
<p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
<p:ajax event="change" update=":form:lblLocation"/>
<f:selectItems value="#{locationStockList.locationSelection}"/>
</p:selectOneMenu>
</h:form>
</h:body>
Convertidor:
@FacesConverter(forClass=Location.class, value="locationConverter")
public class LocationConverter implements Converter, Serializable {
private static final Logger logger = Logger.getLogger(LocationConverter.class.getName());
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.isEmpty())
return null;
try {
Long id = Long.parseLong(value);
Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id);
logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location});
return location;
} catch (NumberFormatException e) {
return new Location();
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.toString().isEmpty() || !(value instanceof Location))
return "";
return String.valueOf(((Location) value).getId());
}
}
Salida de la consola:
// Getter method
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
// Session Bean
INFO: Finding ejb.locations.Location with id=3
// Session Bean
INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Converter
SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3]
// Getter method -> Where did my selected Location go ??
INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0]
En mi caso, olvidé implementar un método correcto de obtención / configuración. Sucedió porque he cambiado muchos atributos a lo largo del desarrollo.
Sin un método de obtención adecuado, JSF no puede recuperar el elemento seleccionado, y sucede lo que dijo BalusC en el punto 1 de su respuesta:
1. El elemento seleccionado falta en la lista de elementos disponibles. Esto puede suceder si la lista de artículos disponibles es servida por un bean con ámbito de solicitud que no se reinicializa adecuadamente en una solicitud posterior, o realiza incorrectamente el trabajo comercial dentro de un método getter que ocasiona que devuelva una lista diferente de alguna manera.