Como digo en el enunciado estoy intentando validar datos editados desde un formularios mediante Spring creando mi propio Validator, ya que puede existir la posibilidad de que en algun momento las validaciones de unos datos puedan estar condicionadas por las validaciones de otros, y por eso he decidido hacerlo asi.
Este sería el bean donde se almacenan los datos del formulario:
Código JAVA:
Ver original
public class ArticuloVO { private int idArticulo; private int idVolumen; private UsuarioVO autor; private EstadoVO estadoArticulo; //Getters y setters
Luego esta el validador que yo he creado especifico para este bean, evidentemente valido solo los datos que me interesa validar y que se van a poder modificar desde el formulario:
Código JAVA:
Ver original
public class ValidadorEditarArticulo implements Validator { @Override ArticuloVO articulo = (ArticuloVO) target; // El titulo es obligatorio ValidationUtils.rejectIfEmptyOrWhitespace(errors, "tituloArticulo", "field.tituloArticulo.required", "Es obligatorio indicar un TITULO para el articulo"); if(!articulo.getTituloArticulo().isEmpty()){ if(!validarLongitudTitulo(articulo.getTituloArticulo())){ errors.rejectValue("tituloArticulo", "field.tituloArticulo.invalid", "El TITULO debe tener entre 10 y 75 caracteres"); } } // El resumen es obligatorio ValidationUtils.rejectIfEmptyOrWhitespace(errors, "resumenArticulo", "field.resumenArticulo.required", "Es obligatorio indicar un RESUMEN para el articulo"); if(!articulo.getResumenArticulo().isEmpty()){ if(!validarLongitudResumen(articulo.getResumenArticulo())){ errors.rejectValue("resumenArticulo", "field.resumenArticulo.invalid", "El RESUMEN debe tener entre 100 y 500 caracteres"); } } if(!articulo.getCoautoresArticulo().isEmpty()){ if(!validarLongitudCoautores(articulo.getCoautoresArticulo())){ errors.rejectValue("coautoresArticulo", "field.coautoresArticulo.invalid", "El campo COAUTORES debe tener entre menos de 100 caracteres"); } } } if(campo.length()>=10 && campo.length()<=75){ return true; } return false; } if(campo.length()>=100 && campo.length()<=500){ return true; } return false; } if(campo.length()<=100){ return true; } return false; } }
Luego esta el controlador desde el cual comprueba si los datos se han validado correctamente y realizo las operaciones oportunas:
Código JAVA:
Ver original
package controladores; @Controller @RequestMapping("privado") public class ControladorFormEditarArticulo { @RequestMapping("editarArticulo") public String editarArticulo(@RequestParam("id") int idArticulo, ModelMap modelo) throws SQLException { ArticuloManager managerArticulo = ManagerFactory.getInstance().getArticuloManager(); modelo.addAttribute("articulo", managerArticulo.getArticulo(idArticulo) ); return "formularioEditarArticulo"; } /** * Registramos el validar que se va a utilizar para este formulario * @param binder */ @InitBinder protected void initBinder(WebDataBinder binder) { binder.setValidator(new ValidadorEditarArticulo()); // registramos el validador } @RequestMapping(value = "actualizarArticulo", method = RequestMethod.POST) // si hay errores volvemos a la vista del formulario if ( result.hasErrors() ) { modelo.addAttribute("articulo", articuloCambios); modelo.addAttribute("errors", result.getAllErrors()); return "formularioEditarArticulo"; } // si no hay errores, manejamos los datos validados... //Obtenemos de nuevo los datos del Articulo que se va a modificar ArticuloManager managerArticulo = ManagerFactory.getInstance().getArticuloManager(); ArticuloVO articulo = managerArticulo.getArticulo(articuloCambios.getIdArticulo()); //AQUI SE HARIAN LAS OPERACIONES PARA GUARDAR EL ARTICULO modelo.addAttribute("success", "Los cambios se han guardado correctamente"); modelo.addAttribute("articulo", articulo); return "formularioEditarArticulo"; } /** * Indica el bean que va a contener los registros del formulario * @return */ @ModelAttribute("articulo") public ArticuloVO populateForm() { return new ArticuloVO(); // creamos el bean para que se pueda popular } }
Y por ultimo la JSP del formulario:
Código HTML:
Ver original
<c:url value="actualizarArticulo.htm" var="destino" /> <form:form cssClass="form-horizontal formulario" method="post" action="${destino}" commandName="articulo"> <c:choose> <c:when test="${not empty errors}"> <div class="error"> <c:forEach items="${errors}" var="err"> <div class="alert alert-error"> </div> </c:forEach> </div> </c:when> <c:when test="${not empty success}"> </c:when> </c:choose> <div class="control-group"> <div class="controls"> <form:input path="idArticulo" readonly="true" type="hidden" value="${articulo.idArticulo}" /> <form:input path="idVolumen" readonly="true" type="hidden" value="${articulo.idVolumen}" /> </div> </div> <div class="control-group"> <form:label class="control-label" path="tituloArticulo">Titulo articulo</form:label> <div class="controls"> <form:input path="tituloArticulo" placeholder="Titulo" value="${articulo.tituloArticulo}" /> </div> </div> <div class="control-group"> <form:label class="control-label" path="resumenArticulo">Resumen articulo</form:label> <div class="controls"> <form:textarea rows="10" cols="20" path="resumenArticulo" placeholder="Resumen del articulo" value="${articulo.resumenArticulo}" /> </div> </div> <div class="control-group"> <form:label class="control-label" path="coautoresArticulo">Resumen articulo</form:label> <div class="controls"> <form:textarea rows="1" cols="20" path="coautoresArticulo" placeholder="Coautores del articulo" value="${articulo.coautoresArticulo}" /> </div> </div> <div class="control-group"> <form:label class="control-label" path="imagenArticulo">Url imagen</form:label> <div class="controls"> <form:input path="imagenArticulo" placeholder="Url imagen" /> </div> </div> <div class="control-group"> <form:label class="control-label" path="pdfArticulo">Pdf imagen</form:label> <div class="controls"> <form:input path="pdfArticulo" placeholder="Url pdf" /> </div> </div> <div class="control-group"> <div class="controls"> </div> </div> </form:form>
Muy bien, pongo todo el codigo, porque a alguien le puede servir de ejemplo ya que el codigo en si funciona.
La funcionalidad es la siguiente, formulario con datos precargados de un objeto ArticuloVO, se modifican los datos en el formulario, se validan y se guardan.
El problema esta en que al validar solo ciertos campos... en el VO quedan campos vacios, en concreto, los objetos:
UsuarioVO autor;
EstadoVO autor;
que no se pueden pasar a traves del formulario, cual es la forma correcta de reinsertar estos objetos, hay alguna forma de hacerlo automatico? o simplemente debo obtener el Articulo de la BBDD y luego utilizar setters para insertar los cambios introducidos en el formulario?