Tengo un mapa que recibo de una copia de la redirección del explorador de un tercero a mi controlador de primavera de la siguiente manera -
@RequestMapping(value = "/capture", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void capture(@RequestParam
final Map<String, String> response)
{
// TODO : perform validations first.
captureResponse(response);
}
Antes de utilizar esta carga útil, lo que necesito hacer la validación no trivial, que implica primero la comprobación de valores no nulos de un mapa, y luego usar esos valores en una validación de la suma. Por lo tanto, me gustaría validar mi carga útil de programación utilizando la interfaz de primavera validador. Sin embargo, no he podido encontrar ningún ejemplo de validación para validar un mapa.
Para validar un objeto Java, entiendo como un validador se invoca al pasar el objeto y un BeanPropertyBindingResult para contener los errores al validador de la siguiente manera -
final Errors errors = new BeanPropertyBindingResult(object, objectName);
myValidator.validate(object, errors);
if (errors.hasErrors())
{
throw new MyWebserviceValidationException(errors);
}
Para un mapa, puedo ver que hay una MapBindingResult
clase que extienda AbstractBindingResult
. Debería simplemente usarlo, y pasar mi mapa en el Object object
y en el validador echo de nuevo a un Map
? Además, ¿cómo sería el método de validación de supports(final Class<?> clazz)
ser implementado en mi validador? Sería simplemente ser como a continuación fragmento de código donde no sólo puede haber un validador de apoyo a esta clase genérica de HashMap? De alguna manera no se siente bien. (Aunque esto no importa ya que me va a inyectar mi validador y utilizarla directamente y no a través de un registro de validación, pero aún curioso.)
@Override
public boolean supports(final Class<?> clazz)
{
return HashMap.class.equals(clazz);
}
Desde entonces, no es un MapBindingResult, estoy seguro de que la primavera debe ser apoyar Mapas para su validación, me gustaría saber cómo. Así que me gustaría saber si este es el camino a seguir, o estoy yendo en la dirección equivocada y hay una mejor manera de hacer esto.
Un saludo, me gustaría hacer esto mediante programación y no a través de anotaciones.
Al igual que pensé, Primavera Validador org.springframework.validation.Validator
hace la validación ayuda de un mapa. Yo probé a mí mismo, y funciona!
He creado un org.springframework.validation.MapBindingResult
pasando en el mapa que necesito para validar y un nombre identificador para ese mapa (para mensajes de error / de nivel raíz global). Este objeto errores se pasa en el validador, junto con el mapa para ser validada como se muestra en el siguiente fragmento de código.
final Errors errors = new MapBindingResult(responseMap, "responseMap");
myValidator.validate(responseMap, errors);
if (errors.hasErrors())
{
throw new MyWebserviceValidationException(errors);
}
El MapBindingResult
extiende AbstractBindingResult
y reemplaza el método getActualFieldValue
para dar su propia aplicación para obtener un mapa de campo en proceso de validación.
private final Map<?, ?> target;
@Override
protected Object getActualFieldValue(String field) {
return this.target.get(field);
}
Por lo tanto, en el interior del validador yo era capaz de utilizar todos los métodos de utilidad útiles proporcionados en org.springframework.validation.ValidationUtils
al igual que utilizamos en un validador de frijol objeto estándar. Por ejemplo -
ValidationUtils.rejectIfEmpty(errors, "checksum", "field.required");
donde "suma de comprobación" es una clave en mi mapa. Ah, la belleza de la herencia! :)
Para las otras validaciones no triviales, simplemente convertir el objeto de mapa y escribí mi código de validación personalizado.
Por lo que las miradas del validador algo así como -
@Override
public boolean supports(final Class<?> clazz)
{
return HashMap.class.equals(clazz);
}
@Override
public void validate(final Object target, final Errors errors)
{
ValidationUtils.rejectIfEmpty(errors, "transactionId", "field.required");
ValidationUtils.rejectIfEmpty(errors, "checksum", "field.required");
final Map<String, String> response = (HashMap<String, String>) target;
// do custom validations with the map's attributes
// ....
// if validation fails, reject the whole map -
errors.reject("response.map.invalid");
}