【发布时间】:2019-05-16 07:45:03
【问题描述】:
问题陈述
从Spring 3 迁移到Spring 4 会在异常处理流程中引发一些异常。
Exception 在org.springframework.web.method.support.InvocableHandlerMethod 类中显示No suitable resolver for argument。
所以每当发生异常时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变量而来的
代码
控制器
@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>
源代码
【问题讨论】:
-
我认为你的意思不是
@CRequestParam,而是@RequestParam -
@geo 及其自定义请求参数
CRequestParam,我们有CRequestparamResolver解析器。 -
@geo 并且整个源代码现已在
https://github.com/santoshjoshi/SpringMVC4签入 -
你能发布一个更完整的堆栈跟踪吗?
-
AFAIK
RequestMappingHandlerAdapter不处理异常,因此无法使用它的参数解析器。看看ExceptionHandlerExceptionResolver.setArgumentResolvers()。我自己从未使用过它,但它看起来很有希望。
标签: java spring spring-mvc spring-4