jsf etiquetas
JSF getValue() versus getSubmittedValue() (4)
Para citar la documentación sobre EditableValueHolder.getSubmittedValue :
Devuelve el valor de valor de submitValue de este componente. Este método solo debe ser utilizado por los métodos encodeBegin () y / o encodeEnd () de este componente, o su Renderer correspondiente.
En general, ni siquiera estarías llamando a getValue . En cambio, el atributo de valor del componente debe estar vinculado a su modelo (un bean, tal vez). La lógica de su negocio interactuaría con el modelo, no con el componente.
Si el valor presentado no se establece como el valor, entonces supongo que alguna validación está fallando. El único problema con eso es que tu evento está siendo despedido. Dos conjeturas para el problema aquí:
- Tiene una referencia obsoleta al objeto componente.
- Estableció el atributo inmediato en un UICommand, lo que significa que el evento se desencadena en una fase en la que el componente estará en un estado inadecuado.
No es posible estar seguro con la información proporcionada.
He estado desarrollando algunas aplicaciones JSF últimamente y estoy preocupado por la incoherencia en las API de componentes web.
Me he dado cuenta de que existe un comportamiento extremadamente impredecible al llamar a .getValue () o .getSubmittedValue () en un objeto componente JSF en el código del lado del servidor. A veces, cuando llamo a .getValue () en un cuadro de lista desplegable, me he dado cuenta de que obtengo el valor ANTES de que haya seleccionado mi valor (por lo que el valor de la última actualización de página), del cual obtiene .getSubmittedValue () yo el valor correcto, como tal:
UIInput name = new UIInput(); // This is the control I have in a bean.
public void submit(ActionEvent ae)
{
someMethod(name.getValue().toString()); // Retrieves the "old" value
someMethod(name.getSubmittedValue().toString()); // Retrieves the correct value
}
Además, he notado que llamar a .getSubmittedValue () en un campo de formulario a veces resulta en una excepción de puntero nulo porque ese valor no se ha instanciado en el objeto componente, en cuyo caso cuando invoco .getValue () en esa circunstancia obtienes el valor correcto, por ejemplo:
HtmlInputText name = new HtmlInputText(); // This is the control I have in a bean.
public void submit(ActionEvent ae)
{
someMethod(name.getValue().toString()); // Retrieves the correct value
someMethod(name.getSubmittedValue().toString()); // Throws NullPointerException
}
¿Es esto solo una "peculiaridad" del marco JSF, o solo estoy usando la API COMPLETAMENTE incorrectamente? Cualquier idea sobre estos dos métodos sería muy apreciada. Aclamaciones.
Dado que este es el resultado # 1 en Google para buscar en getValue vs. getSubmittedValue, me gustaría agregar que la diferencia entre estos es fundamental en la validación (es decir, al escribir un validador personalizado)
Para citar la documentación de API para getSubmittedValue ():
Esto no es nulo solo entre las fases de decodificación y validación, o cuando la validación del componente no ha tenido éxito. Una vez que la conversión y la validación han tenido éxito, el valor (convertido) se almacena en la propiedad de "valor" local de este componente, y el valor enviado se restablece a nulo.
Esto significa que si la validación / conversión ha tenido lugar para la vinculación a la que intenta acceder, debe llamar a getValue (); de lo contrario, tendrá que llamar a getSubmittedValue () y tratar el análisis por sí mismo. El orden en que se producen parece estar dictado por el orden en que aparecen en la interfaz de usuario, pero no creo que eso esté garantizado. Incluso si lo es, no debe contar con que el cambio de campo en su UI no debería romper su código.
Puede detectar si la validación / conversión se ha realizado con solo mirar lo que isLocalValueSet () devuelve. Si devuelve verdadero, entonces la valoración / conversión se ha realizado, por lo que debe llamar a getValue (). De lo contrario, tendrá que llamar a getSubmittedValue () y eso le dará la entrada sin procesar que ingresó el usuario y es probable que desee analizarlo en algo más significativo.
Por ejemplo, un objeto de calendario devolvería un objeto Date cuando se llamó a getValue (), pero se invocó un objeto String cuando getSubmittedValue (). Depende de su convertidor analizar la cadena en una Fecha para que pueda validarse.
Sería genial si la especificación JSF tuviera un método que hiciera esto por nosotros, pero AFAIK no. Si ciertas fechas deben estar antes de otras fechas, y algunas solo son necesarias en ciertas circunstancias, será necesario escribir varios validadores para manejar esto. Por lo tanto, puede convertirse fácilmente en un problema. Esto es similar al hecho de que no puede hacer ningún tipo de validación en un campo en blanco, lo que significa que no puede hacer que ese campo sea requerido condicionalmente. Si la validación se ejecutó en todos los campos, incluso en los vacíos, se podría escribir un validador personalizado para lanzar una excepción si fuera necesario y no lo es. Hay algunas cosas con JSF que son solo un dolor; a menos que / hasta que se arreglen, solo tenemos que lidiar con ellos.
Para hablar sobre los detalles del problema en la publicación original: la diferencia aquí es dónde estás en el ciclo de vida. El método de submit
parece un oyente de acción para un botón, que lo coloca al final del ciclo de vida; las acciones y los oyentes de acción se activan en la fase "Solicitud de invocación" que viene antes de la respuesta de representación, pero después de la validación. Si va a programar en JSF, debe aprender y comprender el ciclo de vida. Vale la pena el tiempo.
Trabajo en xpages que están basados en JSF entonces ... podría ser lo mismo ...
De todos modos, getSubmittedValue (); siempre devuelve lo que ve en la pestaña de red firebug / chrome develepers. Ese es el valor dentro del paquete enviado. Lo tengo mostrado (chrome) en la pestaña de encabezados, en la sección de datos del formulario, llamado $$ xspsubmitvalue.
Por otro lado, getValue () es específico del componente. <- no 100% seguro aquí.
Respuesta de TL; DR :
UIViewRoot viewRoot = context.getViewRoot();
UIInput input = (UIInput)viewRoot.findComponent(":form:inputID");
String inputValueString;
if (input.isLocalValueSet()) {
inputValueString = (String)input.getValue(); //validated and converted already
} else {
inputValueString = (String)input.getSubmittedValue(); //raw input
}
o al menos eso es lo que las otras respuestas dicen que hagan ...
Solo use .getSubmittedValue()
y trate las consecuencias de tener que convertir la entrada sin procesar (si es necesario, si esa entrada sin procesar necesita conversión). .getValue()
se rompe en este sentido, incluso con el código anterior. Retrasa el valor enviado si lo usa y eso es inaceptable.