Spring中的ExceptionHandler

Dav*_*lla 5 java spring spring-mvc

import org.springframework.beans.TypeMismatchException;
import javax.annotation.*;
import javax.servlet.http.*;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(value = "/aa")
public class BaseController {

    @RequestMapping(value = "/bb/{number}", method = RequestMethod.GET, produces = "plain/text")
    public void test(@PathVariable final double number, final HttpServletResponse response) throws IOException {
        throw new MyException("whatever");
    }

    @ResponseBody
    @ExceptionHandler(MyException.class)
    public MyError handleMyException(final MyException exception, final HttpServletResponse response) throws IOException {
        ...
    }

    @ResponseBody
    @ExceptionHandler(TypeMismatchException.class)
    public MyError handleTypeMismatchException(final TypeMismatchException exception, final HttpServletResponse response) throws IOException {
        ...
    }

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    @ExceptionHandler
    public MyError handleException(final Exception exception) throws IOException {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我调用http://example.com/aa/bb/20 ,则会按预期执行函数handleMyException.

但是,如果我调用http://example.com/aa/bb/QQQ, 我希望调用该函数handleTypeMismatchException,而是调用handleException,类型除外TypeMismatchException.

一个令人讨厌的解决方法,它将是测试内部异常的类型handleException(),并调用handleTypeMismatchException异常是否类型TypeMismatchException.

但为什么现在有效?根据异常的类型在运行时选择exceptionhandler?还是在编译时选择?

Pet*_*iuk 4

摘自Spring 官方文档

您可以在控制器中使用@ExceptionHandler方法注释来指定在执行控制器方法期间抛出特定类型的异常时调用哪个方法

您尝试捕获的异常是在实际方法执行之前由 spring 本身生成的(字符串到双精度转换)。捕获它不符合 @ExceptionHandler 的规范。这确实有道理 - 通常您不想捕获框架本身生成的异常。