问题 @ControllerAdvice异常处理程序方法未被调用


我有以下控制器类

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/ 这里。

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


4876
2018-05-16 08:24


起源



答案:


我找到了上述问题的解决方案。实际上@ControllerAdvice需要XML文件中的MVC名称空间声明。或者我们可以将@EnableWebMvc与@ControllerAdvice注释一起使用。


12
2018-05-16 11:42



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


答案:


我找到了上述问题的解决方案。实际上@ControllerAdvice需要XML文件中的MVC名称空间声明。或者我们可以将@EnableWebMvc与@ControllerAdvice注释一起使用。


12
2018-05-16 11:42



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


我有类似的问题。

管理在2017年9月修复它。

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

解决方案是将其添加到ComponentScan中,如下所示:

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

2
2017-10-09 12:59



如果它是一个Spring Boot应用程序,你可以使用@SpringBootApplication(scanBasePackages = {“x.y.z.services”,“x.y.z.controllers”,“x.y.z.exceptions”}) - Paulo Merson


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 " />

0
2018-05-16 14:23





您只需执行以下两个步骤:

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

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


0
2017-11-23 10:32





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

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

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

或者您的控制器建议应该只有一个带注释的方法:

@ExceptionHandler({
    Exception.class
})

-1
2018-05-16 08:37