Spring 4 Exception Handling : No suitable resolver for argument

19,654

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

Share:
19,654
Santosh Joshi
Author by

Santosh Joshi

programmer. You can fork me at github https://github.com/santoshjoshi

Updated on July 06, 2022

Comments

  • Santosh Joshi
    Santosh Joshi almost 2 years

    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