开发者

Custom Exception Messages with Spring framework

I am using spring and Hibernate in my application,There is one scenario where i insert same records morethan once ,So application correctly throwing Constraint Exception because i applied Unique constraint in one of the db column.So far is everything fine.

But i have to 开发者_运维知识库display some custom message like "record already exists'" instead of showing Hibernate Exception.

How can i do with Spring framework.

Any hints or examples greatly appreciated.

Regards,

Raju


Yes you can exception in controller:

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

Of cause you can catch any tpe of exception just insert it as the parameter to @ExceptionHandler

Hope it helps.


I am facing the same issue but in my case either one or several fields can be duplicated (username or email). Hence the org.hibernate.exception.ConstraintViolationException is not specific enough to say whether the username or email caused this exception to be thrown and what message to display in consequence.

I just looked at danny.lesnik's answer but it's not great as it simply redirects to a "dedicated" page. Assuming you simply redirect to the page user was on would avoid the creation of a new page you'd say. However I assume you already have a Spring validator doing some form validation work. That's why in my case I decided to simply do my fields (username and email) duplication checks in the same place (in the Validator). Seems like a more suitable, consistent (located with the rest of the validation) and cleaner solution.

Here is some code to illustrate:

My Controller

@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";
        }
    }
    ...
}

My Validator

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");

        }
    }
}

I'm unsure if that's the best way to do this but thought my solution would allow more extension (you can add various checks on any other constraint).

Hope it helps others and it'd also be interesting to get more devs' thought on this solution.


you can catch the exception thrown by spring/hibernate and throw one of your own exceptions which would hold the 'record already exists' message, you could even look up a localized message from a resource bundle and display this message on your presentation layer (e.g. jsp)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜