2011-08-27 30 views
6

Estoy usando Spring y Hibernate en mi aplicación, hay un escenario en el que inserto los mismos registros más de una vez, por lo que la aplicación arroja correctamente Excepción de restricción porque apliqué la restricción Unique en una de las columnas de db. ahora está todo bien.Mensajes de excepción personalizados con marco de Spring

Pero tengo que mostrar algunos mensajes personalizados como "el registro ya existe" en lugar de mostrar la excepción de Hibernate.

¿Cómo puedo hacer con el marco de primavera.

Cualquier sugerencia o ejemplos muy apreciados.

Saludos,

Raju

Respuesta

6

Sí se puede excepción en el controlador:

@ExceptionHandler(Exception.class) 
     public ModelAndView handleMyException(Exception exception) { 
     ModelAndView mv = new ModelAndView("error"); 
     mv.addObject("message"."record already exists"); 
     return mv; 
       } 

De la causa que usted puede atrapar cualquier excepción excepto insértelo como el parámetro a @ExceptionHandler

Espero que ayude.

+0

+1 y gracias !! – Gabber

0

se puede coger la excepción lanzada por el resorte/hibernación y lanzar una de sus propias excepciones que obstaculicen el 'registro ya existe' mensaje, incluso se podría buscar una localizada mensaje de un paquete de recursos y mostrar este mensaje en la capa de presentación (por ejemplo, JSP)

+0

Incluso estoy pensando lo mismo con Extending Exception, crearé una excepción. Pero ¿cómo puedo mostrar el mismo mensaje en la capa de preestablecimiento de Spring. – Raj

+0

cuando un usuario intenta agregar un registro duplicado puede atrapar la excepción de hibernación, luego en su capa de servicio (es decir, donde llama a su lógica de backend) intentaría insertar el registro, capturar la excepción y luego reenviar a una página de error , algo así – eon

2

Me enfrenta el mismo problema, pero en mi caso, uno o varios campos se pueden duplicar (nombre de usuario o correo electrónico). Por lo tanto, el org.hibernate.exception.ConstraintViolationException no es lo suficientemente específico para decir si el nombre de usuario o el correo electrónico provocaron que se lanzara esta excepción y qué mensaje mostrar en consecuencia.

Acabo de mirar danny.lesnik's answer pero no es genial, ya que simplemente redirige a una página "dedicada". Asumir que simplemente redirigir a la página en la que estaba el usuario evitaría la creación de una página nueva que diría. Sin embargo, supongo que ya tiene un Spring validator haciendo algún trabajo de validación de formularios. Es por eso que en mi caso decidí simplemente hacer mis comprobaciones de duplicación de campos (nombre de usuario y correo electrónico) en el mismo lugar (en el Validador). Parece una solución más adecuada, consistente (ubicada con el resto de la validación) y más limpia.

Aquí hay un código para ilustrar:

Mi controlador

@Controller 
public class WebController { 

    @Autowired 
    private UserServiceImpl userService; 

    @Autowired 
    private CustomUserDetailsValidator customUserDetailsValidator; 

    ... 
    @RequestMapping(value = "/login/create-account", method = RequestMethod.POST) 
    public String createAccount(@ModelAttribute("user") CustomUserDetails user, BindingResult result, Model model, SessionStatus status) { 

     customUserDetailsValidator.validate(user, result); 

     if(result.hasErrors()){ 
      model.addAttribute("user", user); 

      // Print the errors to the console - FIXME: log error instead 
       System.out.println("Validation errors:"); 
       for (FieldError error : result.getFieldErrors()) { 
        System.out.println(error.getField() + " - " + error.getDefaultMessage()); 
      } 

      return "login/create-account"; 
     } 
     else{ 
      userService.registerUser(user);    
      return "redirect:/login/create-account-success"; 
     } 
    } 
    ... 
} 

Mi Validador

public class CustomUserDetailsValidator implements Validator { 

    @Autowired 
    private UserServiceImpl userService; 
    ... 

    @Override 
    public void validate(Object target, Errors errors) { 

     // some simple validations 

     // and here some complex validation (is username or email used duplicated?) 
     if(errors.getAllErrors().size() == 0){ 

      if (userService.doesUsernameAlreadyExist(user.getUsername())) 
       errors.rejectValue(usernameFieldName, "duplicate.username","username already exists"); 

      if (userService.doesEmailAlreadyExist(user.getEmail())) 
       errors.rejectValue(emailFieldName, "duplicate.email","email already exists"); 

     } 
    } 
} 

estoy seguro si esa es la mejor manera de hacer esto, pero pensé que mi solución sería permitir más extensión (puede agregar varias verificaciones en cualquier otra restricción).

Espero que ayude a los demás y también sería interesante obtener más pensamientos de los desarrolladores sobre esta solución.

Cuestiones relacionadas