java Spring 4 异常处理:没有合适的参数解析器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25030008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 07:10:51  来源:igfitidea点击:

Spring 4 Exception Handling : No suitable resolver for argument

javaspringspring-mvcspring-4

提问by Santosh Joshi

Problem Statement

问题陈述

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

迁移到Spring 4fromSpring 3会在异常处理流程中引发一些异常。异常No suitable resolver for argumentorg.springframework.web.method.support.InvocableHandlerMethod课堂上说。

So whenever and exception occurs Springtries 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

因此,每当发生异常时,都会Spring尝试找到它获取的异常处理程序,但是当它尝试填充方法参数或异常处理程序时,它会抛出以下异常

Failed to invoke @ExceptionHandler method:

无法调用@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 details:

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)

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

它基本上用于@CRequestParam("p") String p变量

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

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>

Source Code

源代码

https://github.com/santoshjoshi/SpringMVC4

https://github.com/santoshjoshi/SpringMVC4

回答by Santosh Joshi

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 codeis available at git

完整的源代码可在git

回答by Fakhri Satii Boto

Solved the problem by providing the implementation of WebApplicationInitializer

通过提供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);

}