8

Problem Statement

Migration to Spring 4 from Spring 3 induces some exceptions in exception handling flow. The Exception says No suitable resolver for argument in the org.springframework.web.method.support.InvocableHandlerMethod class.

So whenever and exception occurs Spring tries to find the Exception Handler which it gets but when it tries to populate the method arguments or exception Handler it throws the below exception

Failed to invoke @ExceptionHandler method:

 public org.springframework.web.servlet.ModelAndView HelloController.handleCustomException(CustomGenericException, javax.servlet.http.HttpServletRequest, org.springframework.web.servlet.ModelAndView) java.lang.IllegalStateException: No suitable resolver for argument [2] [type=org.springframework.web.servlet.ModelAndView] 

HandlerMethod details:

Controller [HelloController] Method [public org.springframework.web.servlet.ModelAndView HelloController.handleCustomException(CustomGenericException, javax.servlet.http.HttpServletRequest,org.springframework.web.servlet.ModelAndView)] at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues( InvocableHandlerMethod.java:169) 

It basically comes for @CRequestParam("p") String p variable

Code

Controller

@RequestMapping(method = RequestMethod.GET, value="/exception2") public String getException1(ModelMap model, @CRequestParam("p") String p) { System.out.println("Exception 2 "+ p); throw new CustomGenericException("1","2"); } 

Exception Handler

@ExceptionHandler(CustomGenericException.class) public ModelAndView handleCustomException(CustomGenericException ex, HttpServletRequest request, @CRequestParam("p") String p) { ModelAndView model = new ModelAndView("error/generic_error"); model.addObject("exception", ex); System.out.println("CustomGenericException "); return model; } 

Annotations

@Target( { ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CRequestParam { String value() default ""; } 

Param Resolver

public class CRequestparamResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { CRequestParam requestParamAnnotation = methodParameter.getParameterAnnotation(CRequestParam.class); if(requestParamAnnotation==null){ return false; } return true; } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { CRequestParam requestParamAnnotation = methodParameter .getParameterAnnotation(CRequestParam.class); if (requestParamAnnotation != null) { String requestParamName = requestParamAnnotation.value(); if (StringUtils.hasText(requestParamName)) { return webRequest.getParameter(requestParamName); } } return null; } 

XML Configuration

<bean class="com.mkyong.common.resolver.AnnotationMethodHandlerAdapterConfigurer" init-method="init"> <property name="customArgumentResolvers"> <list> <bean class="com.mkyong.common.resolver.CRequestparamResolver" /> </list> </property> </bean> <bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"> <property name="customArgumentResolvers"> <list> <bean class="com.mkyong.common.resolver.CRequestparamResolver" /> </list> </property> </bean> 

Source Code

https://github.com/santoshjoshi/SpringMVC4

6
  • I presume that instead of @CRequestParam you mean @RequestParam Commented Jul 30, 2014 at 6:30
  • @geoand its custom request parameter CRequestParam for which we have CRequestparamResolver resolver. Commented Jul 30, 2014 at 6:37
  • @geoand the whole source code has now been checked in at https://github.com/santoshjoshi/SpringMVC4 Commented Jul 30, 2014 at 6:57
  • Can you please post a more complete stacktrace? Commented Jul 30, 2014 at 7:03
  • AFAIK RequestMappingHandlerAdapter does not handle the exception so it's argument resolvers cannot be used. Have a look at ExceptionHandlerExceptionResolver.setArgumentResolvers(). I never used it myself but it looks promising. Commented Jul 30, 2014 at 7:05

3 Answers 3

8

Solved the problem by passing the custom arguments in request itself.

code is as below :

Controller

@RequestMapping(method = RequestMethod.GET, value = "/exception2") public String getException1(ModelMap model, @CRequestParam("p") String p, HttpServletRequest request) { System.out.println("Exception 2 " + p); request.setAttribute("p", p); throw new CustomGenericException("1", "2"); } 

Exception Handler

@ExceptionHandler(CustomGenericException.class) public ModelAndView handleCustomException(CustomGenericException ex, HttpServletRequest request) { ModelAndView model2 = new ModelAndView("error/generic_error"); model2.addObject("exception", ex); System.out.println(request.getAttribute("p")); System.out.println("CustomGenericException "); return model2; } 

Complete source code is available at git

Sign up to request clarification or add additional context in comments.

Comments

2

In my case, I didn't add @RequestBody to my client-interface so it didn't know how to resolve the parameters.

Comments

-1

Solved the problem by providing the implementation of WebApplicationInitializer

public class SpringDispatcherConfig implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext Contianer = new AnnotationConfigWebApplicationContext(); Contianer.register(SpringConfig.class); Contianer.setServletContext(servletContext); DispatcherServlet dispatcherServlet = new DispatcherServlet(Contianer); dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); Dynamic servlet = servletContext.addServlet("spring",dispatcherServlet); servlet.addMapping("/"); servlet.setLoadOnStartup(1); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.