2012-08-13 19 views
10

Estoy usando la clase Preconditions de Google para validar los datos de entrada del usuario.
Pero me preocupa cuál es el mejor punto para verificar los datos de entrada del usuario usando la clase Preconditions.
En primer lugar, me escribió código de comprobación de validación en el controlador, como a continuación:Verifique las condiciones previas en el controlador o la capa de servicio

@Controller 
... 
public void register(ProductInfo data) { 
    Preconditions.checkArgument(StringUtils.hasText(data.getName()), 
     "Empty name parameter."); 
    productService.register(data); 
} 

@Service 
... 
public void register(ProductInfo data) { 
    productDao.register(data); 
} 

Pero pensé que register método en la capa de servicio estaría utilizando otro método controlador, como a continuación:

@Controller 
... 
public void register(ProductInfo data) { 
    productService.register(data); 
} 
public void anotherRegister(ProductInfo data) { 
    productService.register(data); 
} 

@Service 
... 
public void register(ProductInfo data) { 
    Preconditions.checkArgument(StringUtils.hasText(data.getName()), 
     "Empty name parameter."); 
    productDao.register(data); 
} 

Por otra parte , el método de capa de servicio se usaría en un solo controlador.
Estaba confundido. ¿Cuál es la mejor forma de verificar las condiciones previas en el controlador o servicio?
Gracias de antemano.

Respuesta

17

Idealmente lo haría en ambos lugares. Pero sus confundir dos cosas diferentes:

  • Validación (con control de errores)
  • Programación Defensivie (también conocido como afirmaciones, también conocido como diseño por contrato).

Usted absolutamente debe hacer validación en el controlador y programación defensiva en su servicio. Y aquí está el por qué.

Necesita validar para formularios y solicitudes REST para que pueda enviar un error razonable de nuevo al cliente. Esto incluye qué campos son malos y luego hacer la localización de los mensajes de error ... etc ... (su ejemplo actual me enviaría un mensaje de error horrible 500 con un seguimiento de pila si la propiedad ProductInfo.name fuera nula).

Spring tiene un solution for validating objects en el controlador.

La programación defensiva se realiza en la capa de servicio, pero no validación porque usted no tiene acceso a la configuración regional para generar mensajes de error apropiados. Algunas personas lo hacen, pero Spring realmente no te ayuda allí.

La otra razón por la cual la validación no se hace en la capa de servicio es que el ORM ya lo hace típicamente a través de la especificación de validación JSR Bean (hibernación) pero no genera mensajes de error razonables.

Una estrategia personas hacen es crear allí propia biblioteca precondiciones utilidades que arroje deriva encargo RuntimeException s en lugar de la guayaba (y bienes comunes lang) IllegalArgumentException y IllegalStateException y luego try ... catch las excepciones en el controlador de la conversión a error de validación mensajes.

2

No hay una "mejor" manera. Si cree que el servicio va a ser utilizado por múltiples controladores (u otras piezas de código), entonces puede tener sentido hacer los controles allí. Si es importante que su aplicación verifique solicitudes inválidas mientras todavía están en el controlador, puede tener sentido hacer los controles allí. Estos dos, como habrás notado, no son mutuamente excluyentes. Es posible que deba verificar dos veces para cubrir ambos escenarios.

Otra posible solución: use Bean Validation (JSR-303) para colocar las verificaciones (precondiciones) en el bean ProductInfo. De esta forma, solo especifica los controles una vez y cualquier cosa que necesite puede validar rápidamente el bean.

+0

Definitivamente de acuerdo en que debe usar la validación de bean, especialmente si su DAO está usando ORM. – hyness

0

Creo que en su caso especial debe verificarlo en la capa de Servicio y devolver una excepción al Controlador en caso de error de integridad de datos.

@controller 
public class MyController{ 

@ExceptionHandler(MyDataIntegrityExcpetion.class) 
public String handleException(MyDataIntegrityExcpetion ex, HttpServletRequest request) { 
    //do someting on exception or return some view. 
} 

} 

También depende de lo que está haciendo en el controlador. si devuelve View o simplemente usando @ResponseBody Annotation. Spring MVC tiene una buena solución "lista para usar" para la validación de entrada/dat. Le recomiendo que revise estas bibliotecas.

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/validation.html

0

condiciones previas, validaciones, ya sea simple o negocio debe ser manejado en la capa de filtro o por interceptores, incluso antes de alcanzar la capa del controlador o servicio.

El peligro si lo comprueba en su capa de controlador, está violando el principio de responsabilidad única de un controlador, cuyo único propósito es delegar la solicitud y la respuesta.

Poner condiciones previas en la capa de servicio está introduciendo preocupaciones transversales en el negocio principal.

El filtro o inceptor está construido para este propósito. Poner condiciones previas en la capa de filtro o en los interceptores también le permite "seleccionar y unir" las reglas que puede colocar en la pila para cada solicitud de servlet, sin limitar una regla en particular a solo una solicitud de servlet o introducir una duplicación.

Cuestiones relacionadas