@ControllerAdvice不处理抛出的异常

时间:2016-03-04 14:14:43

标签: spring spring-mvc exception-handling

存储库:

@Repository
public class UserRepositoryImpl implements UserRepository {
@PersistenceContext
public EntityManager entityManager;
public User findUserById(Long id) throws RepositoryException {
    try {
        User foundUser = entityManager.find(User.class, id);
        if (foundUser == null) {
            throw new RepositoryException();
        }
        return foundUser;
    } catch (Exception e) {
        throw new RepositoryException();
    }
}
}

服务类:

@Service
@Transactional(rollbackFor = DataIntegrityViolationException.class)
public class UserServiceImpl implements UserService {

private UserRepository userRepository;

@Autowired
public void setUserRepository(UserRepository userRepository) {
    this.userRepository = userRepository;
}

public User findUserById(Long id) throws ServiceException {
    try {
        return userRepository.findUserById(id);
    } catch (Exception e) {
        throw new ServiceException();
    }
}
}

控制器:

@RestController
@RequestMapping("/api/users")
public class UserController {

@Autowired
private UserService userService;

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User findUserbyId(@PathVariable Long id) throws RestApiException {
    try {
        return userService.findUserById(id);
    } catch (Exception e) {
        throw new RestApiException();
    }
}
}

建议控制器:

@ControllerAdvice
public class AdviceController {
@ExceptionHandler(RepositoryException.class)
@ResponseBody
@ResponseStatus(HttpStatus.NOT_FOUND)
public ExceptionDetails handleDBException(RepositoryException e) {
    ExceptionDetails exceptionDetails = new ExceptionDetails("DB", e.getMessage());
    return exceptionDetails;
}

@ExceptionHandler(ServiceException.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ExceptionDetails shandleServiceException(ServiceException e) {
    ExceptionDetails exceptionDetails = new ExceptionDetails("SERVICE", e.getMessage());
    return exceptionDetails;
}

@ExceptionHandler(RestApiException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ExceptionDetails handleRestApiException(RestApiException e) {
    ExceptionDetails exceptionDetails = new ExceptionDetails("REST", e.getMessage());
    return exceptionDetails;
}
}

ExceptionDetails类:

public class ExceptionDetails {

private String code;
private String message;

public ExceptionDetails(String code, String message) {
    this.code = code;
    this.message = message;
}

}

每当我使用带有url:http://localhost:8080/springapp/api/users/7的postman进行请求时,其中id不在db中存在,我猜建议控制器应该已经处理了抛出的异常,但我得到以下内容:

Hibernate: 
    select
        user0_.id as id1_3_0_,
        user0_.email as email2_3_0_,
        user0_.registrationId as registra3_3_0_,
        user0_.username as username4_3_0_ 
    from
        User user0_ 
        where
        user0_.id=?
Mar 04, 2016 11:21:23 AM org.apache.catalina.core.StandardWrapperValve     invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path     [/notofatespring] threw exception [Request processing failed; nested     exception is com.adaptiv.notofatespring.exception.RestApiException] with root     cause
com.adaptiv.notofatespring.exception.RestApiException
    at     com.adaptiv.notofatespring.controller.UserController.findUserbyId(UserControl    ler.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at     sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at     sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.    java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at     org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(Invoca    bleHandlerMethod.java:221)
    at     org.springframework.web.method.support.InvocableHandlerMethod.invokeForReques    t(InvocableHandlerMethod.java:136)
    at     org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandler    Method.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAd    apter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
    at     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAd    apter.handleInternal(RequestMappingHandlerAdapter.java:731)
    at     org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handl    e(AbstractHandlerMethodAdapter.java:85)
    at     org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServle    t.java:959)
    at     org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet    .java:893)
    at     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServ    let.java:968)
    at     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:    859)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at     org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.jav    a:844)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationF    ilterChain.java:303)
    at     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCha    in.java:208)
    at         org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationF    ilterChain.java:241)
    at     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCha    in.java:208)
    at     org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.jav    a:220)
    at     org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.jav    a:122)
    at     org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.    java:505)
    at     org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at     org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at     org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at     org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:    116)
    at     org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at     org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Proces    sor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(Abstract    Protocol.java:625)
    at     org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:3    16)
    at     java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:114    2)
at     java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:61    7)
    at     org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.jav    a:61)
    at java.lang.Thread.run(Thread.java:745)

知道为什么控制器建议没有处理异常?

1 个答案:

答案 0 :(得分:0)

您最有可能在异常处理程序中缺少@EnableWebMvc注释。根据我的理解,您的异常处理程序应该是这样的。

@EnableWebMvc
@ControllerAdvice
public class AdviceController {

同样,在声明时,您还可以提供应扫描的软件包。例如

@ControllerAdvice(basePackages = {"com.concretepage.controller"} ) 

如果可能的话,为了测试目的,您可以返回jsp,例如

@ExceptionHandler(SQLException.class)

public String handleSQLException(HttpServletRequest request, Exception ex){

        logger.info("SQLException Occured:: URL="+request.getRequestURL());

        return "database_error";

    }