Spring @ExceptionHandler(Exception.class)总是被调用。为什么?

时间:2011-11-15 13:27:28

标签: java spring spring-mvc

我有一个代码结构,其中有一个基本控制器类,提供基本的require方法,后跟从这个基类继承的特定控制器类。现在每当我对子类中提到的服务之一进行REST服务调用时,将调用使用@ExceptionHandler注释的基类方法,然后调用实际的请求映射方法。这不会导致问题,因为我得到了所需的响应。但我担心它可能带来的性能问题,并希望消除对该方法的不必要的控制流程。任何建议/解决方案?这是我的代码 -

    public class BaseApiController extends AbstractController {
        protected @Autowired HttpServletRequest request;



        protected ServerResponse serverResponse() {
            ServerResponse serverResponse = new ServerResponse();
            return serverResponse;
        }


        @ExceptionHandler(Exception.class)
        public @ModelAttribute("response") ServerResponse exceptionHandler(Exception ex) {
            ServerResponse response = new ServerResponse();
            response.setError(new Error("500", ex.getMessage(), ex.getStackTrace(), ex));

            Log.error(this.getClass(),
                    "[" + this.getClass().getSimpleName() + ": baseApiExceptionHandler] Response: " + response.toString());
            return response;
        }
    }


@Controller
@RequestMapping("/test")    
public class TestController extends BaseApiController {

    @Autowired
    private UserService userService;


    @RequestMapping(value = "/ping", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public @ModelAttribute("response") ServerResponse ping() {
        Log.debug(this.getClass(), "testing ping...");
        ServerResponse serverResponse = this.serverResponse();
        serverResponse.setResult("SmartLBS says hi");

        Log.debug(this.getClass(), "responding: " + serverResponse.toString());
        return serverResponse;
    }
}

使用以下堆栈跟踪调用它。

ERROR UserController:73 - [UserController: baseApiExceptionHandler] Response: ServerResponse{result=null, error=Error{code='500', message=null, stackTrace=[sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method), sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39), sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27), java.lang.reflect.Constructor.newInstance(Constructor.java:513), org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147), org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104), org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137), org.springframework.web.servlet.mvc.method.annotation.support.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:83), org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:101), org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:74), org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:155), org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117), org.springframework.web.method.annotation.ModelFactory.invokeModelAttributeMethods(ModelFactory.java:118), org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:100), org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:626), org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:590), org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80), org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900), com.locationguru.framework.base.BaseDispatcherServlet.doDispatch(BaseDispatcherServlet.java:31), org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827), com.locationguru.framework.base.BaseDispatcherServlet.doService(BaseDispatcherServlet.java:24), org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:874), org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:779), javax.servlet.http.HttpServlet.service(HttpServlet.java:621), com.locationguru.framework.base.BaseDispatcherServlet.service(BaseDispatcherServlet.java:38), javax.servlet.http.HttpServlet.service(HttpServlet.java:722), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210), org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210), com.locationguru.smartlbs.middleware.auth.AppAuthFilter.doFilterInternal(AppAuthFilter.java:84), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76), org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346), org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210), com.locationguru.smartlbs.middleware.auth.UserAuthFilter.doFilterInternal(UserAuthFilter.java:88), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76), org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346), org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210), org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224), org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:185), org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472), org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151), org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100), org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929), org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118), org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405), org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269), org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515), org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302), java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908), java.lang.Thread.run(Thread.java:680)], exception=java.lang.Exception}, reqTime=1321362850208, respTime=null}

2 个答案:

答案 0 :(得分:1)

public @ModelAttribute("response") ServerResponse exceptionHandler

上面代码中的@ModelAttribute声明导致了问题。用@ResponseBody替换它,问题得到解决。

答案 1 :(得分:0)

你确定方法

@ExceptionHandler
public @ModelAttribute("response") ServerResponse exceptionHandler(Exception ex) {
   ..
   response.setError(new Error("500", ex.getMessage(), ex.getStackTrace(), ex));

没有异常被调用?!即使用ex=null调用它,也会导致空指针异常!

真的,我相信你的观察中有一些错误。

相关问题