问题陈述
Spring 4从迁移到会Spring 3在异常处理流程中引发一些异常。例外No suitable resolver for argument在org.springframework.web.method.support.InvocableHandlerMethod课堂上说。
Spring 4
Spring 3
No suitable resolver for argument
org.springframework.web.method.support.InvocableHandlerMethod
因此,无论何时发生异常,都Spring试图找到它所获得的异常处理程序,但是当它试图填充方法参数或异常处理程序时,它将引发以下异常
Spring
无法调用@ExceptionHandler方法:
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详细信息:
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)
它基本上是@CRequestParam("p") String p 可变的
@CRequestParam("p") String p
码
控制者
@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"); }
异常处理程序
@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; }
注解
@Target( { ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CRequestParam { String value() default ""; }
参数解析器
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配置
<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>
源代码
https://github.com/santoshjoshi/SpringMVC4
通过在请求本身中传递自定义参数来解决该问题。
代码如下:
@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"); }
@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; }
完整的源代码 可以在git上找到