I have a parent class with @ExceptionHandler and a subclass with its own version. I get an ambiguous method error

Parent:

@ExceptionHandler(NoUserException.class) protected ModelAndView handleException(NoUserException e) { Map<String, Object> model = new HashMap<String, Object>(); model.put(ModelKeys.HOST_KEY, "message"); return new ModelAndView("noAccess",model); } 

Child:

 @ExceptionHandler(NoUserException.class) protected void handleException(NoUserException e, HttpServletRequest request, HttpServletResponse response) throws IOException { logger.error("Invalid user."); respond(CLIENT_USER_ERROR,response); } 

Yes, I need them to have different parameters and outputs.

+6
source share
2 answers

You cannot have two methods with the same exception handler, sorry, it just is not supported. The code that solves them does not detect between super-subclasses and considers the subclass “more specific”. The code is in org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver if you're interested. It would not be easy to make your own implementation of AbstractHandlerExceptionResolver based on one that views the method directly on the controller for a more specific result than the legacy method.

edit: a personal comment, I eventually found that I’d better suppress the desire to use “inheritance as a tool for creating templates” when creating Spring annotation-controlled MVC controllers. Viewing the code is essentially awkward and procedural, so we do a separate “review layer” in the first place. Too micro-approach to DRY and "reuse" will not help you. If this violates the Liskov substitution principle, I do not. YMMV, of course.

+8
source

Why not just delegate the implementation of handleException() another method?

 // superclass protected ModelAndView handleExceptionImpl( NoUserException e, HttpServletResponse response) { Map<String, Object> model = new HashMap<String, Object>(); model.put(ModelKeys.HOST_KEY, "message"); return new ModelAndView("noAccess",model); } @ExceptionHandler(NoUserException.class) protected ModelAndView handleException( NoUserException e, HttpServletResponse response) { return handleExceptionImpl(e, response); } // subclass @Override protected ModelAndView handleExceptionImpl( NoUserException e, HttpServletResponse response) { logger.error("Invalid user."); respond(CLIENT_USER_ERROR,response); } 
+1
source

Source: https://habr.com/ru/post/920815/


All Articles