【问题标题】:@ControllerAdvice exception handler method are not get called@ControllerAdvice 异常处理方法不会被调用
【发布时间】:2017-11-14 10:47:41
【问题描述】:

我有以下控制器类

package com.java.rest.controllers;
@Controller
@RequestMapping("/api")
public class TestController {

@Autowired
private VoucherService voucherService;


@RequestMapping(value = "/redeemedVoucher", method = { RequestMethod.GET })
@ResponseBody
public ResponseEntity redeemedVoucher(@RequestParam("voucherCode") String voucherCode) throws Exception {
    if(voucherCode.equals( "" )){
        throw new MethodArgumentNotValidException(null, null);
    }
    Voucher voucher=voucherService.findVoucherByVoucherCode( voucherCode );
    if(voucher!= null){
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=utf-8");
        voucher.setStatus( "redeemed" );
        voucher.setAmount(new BigDecimal(0));
        voucherService.redeemedVoucher(voucher);
        return new ResponseEntity(voucher, headers, HttpStatus.OK);

    }
    else{
        throw new ClassNotFoundException();
    }
};

}

对于异常处理,我使用 Spring3.2 建议处理程序如下

package com.java.rest.controllers;


@ControllerAdvice
public class VMSCenteralExceptionHandler extends ResponseEntityExceptionHandler{

@ExceptionHandler({
    MethodArgumentNotValidException.class
})
public ResponseEntity<String> handleValidationException( MethodArgumentNotValidException methodArgumentNotValidException ) {
    return new ResponseEntity<String>(HttpStatus.OK );
}

 @ExceptionHandler({ClassNotFoundException.class})
        protected ResponseEntity<Object> handleNotFound(ClassNotFoundException ex, WebRequest request) {
            String bodyOfResponse = "This Voucher is not found";
            return handleExceptionInternal(null, bodyOfResponse,
              new HttpHeaders(), HttpStatus.NOT_FOUND , request);
        }

}

我已将 XML bean 定义定义为

<context:component-scan base-package="com.java.rest" />

控制器抛出的异常不被控制器通知处理器处理。我已经用谷歌搜索了几个小时,但找不到任何参考为什么会发生这种情况。 我按照http://www.baeldung.com/2013/01/31/exception-handling-for-rest-with-spring-3-2/ 的描述进行了操作。

如果有人知道,请告诉为什么处理程序没有处理异常。

【问题讨论】:

    标签: spring spring-mvc


    【解决方案1】:

    我找到了解决上述问题的方法。实际上@ControllerAdvice 需要在 XML 文件中声明 MVC 命名空间。或者我们可以使用带有@ControllerAdvice 注解的@EnableWebMvc。

    【讨论】:

    • 为了更清楚这个答案, ResponseEntityExceptionHandler 的子类必须包含在 @ComponentScan 的路径中,以便 Spring 容器检测到它。我认为文档对此不是很清楚。希望这可以节省一些人的时间。
    • 您能否澄清一下“需要 MVC 命名空间声明”的含义?
    • @EricB。通过 MVC 命名空间声明,我的意思是,我们的配置 xml 文件(例如 applicationConfig.xml)中应该有 。如果我们没有在 xml 文件中使用 那么我们必须使用带有 ControllerAdvice 注释的 EnableWebMvc。
    • @VishalSingh 我在 mu\y 应用程序中面临同样的问题。@ControllerAdvice 异常处理程序方法未被调用。我已尝试使用给定的解决方案,但问题仍然存在。你能帮帮我吗摆脱它
    • @rachana,请检查您的控制器建议 bean 是否在您的扫描路径中。还要检查你的 spring 版本。@ControllerAdvice 注解适用于 spring3.2 或更高版本。
    【解决方案2】:

    我也有类似的问题。

    设法在 2017 年 9 月修复它。

    我的情况是异常处理程序在它自己的 com.example.Exceptions 包中,问题是它没有被 Spring ComponentScan 扫描。

    解决方案是像这样在 ComponentScan 中添加它:

    @ComponentScan({ "x.y.z.services", "x.y.z.controllers", "x.y.z.exceptions" })
    

    【讨论】:

    • 如果是Spring Boot应用,可以使用@SpringBootApplication(scanBasePackages = {"x.y.z.services", "x.y.z.controllers", "x.y.z.exceptions"})
    【解决方案3】:
    public class VMSCenteralExceptionHandler implements HandlerExceptionResolver {
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        }
    }
    

    并将您的 bean 添加到您的 config.xml 中

    <bean class="com.java.rest.controllers.VMSCenteralExceptionHandler " />
    

    【讨论】:

      【解决方案4】:

      您只需要执行这两个步骤:

      1. 在全局异常处理程序类之上添加 @ControllerAdvice
      2. 在组件扫描中添加您的异常类的包名称,即

        <context:component-scan base-package="com.hr.controller,com.hr.exceptions" />

      【讨论】:

        【解决方案5】:

        我认为问题可能是您的控制器方法抛出 Exception 但您的 @ControllerAdvice 方法捕获特定异常。要么将它们组合成一个捕获Exception 的处理程序,要么让你的控制器抛出那些特定的异常。

        所以你的控制器方法签名应该是:

        public ResponseEntity redeemedVoucher(@RequestParam("voucherCode") String voucherCode) throws MethodArgumentNotValidException, ClassNotFoundException;
        

        或者你的控制器通知应该只有一个带有注释的方法:

        @ExceptionHandler({
            Exception.class
        })
        

        【讨论】:

          猜你喜欢
          • 2018-07-13
          • 2014-08-26
          • 1970-01-01
          • 2022-10-14
          • 1970-01-01
          • 2017-11-23
          • 2020-12-02
          • 2019-06-04
          相关资源
          最近更新 更多