Spring Boot:异常处理,如果应用程序启动后mongo diconnects

时间:2017-04-17 18:12:31

标签: spring mongodb spring-boot exception-handling spring-session

我的春季启动应用程序在启动时使用mongo,启动非常顺利。 启动后,我关闭mongo并点击我的应用程序的任何控制器。但控件永远不会达到控制器级别因此@ControllerAdvice无法处理mongo异常。 我还尝试创建一个通用异常处理程序,并在application.java中注册该类,如此

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {

    return container -> {
        ErrorPage error401Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/error");
        container.addErrorPages(error401Page);
    };

只要mongo启动并运行,这样就可以正常工作。 一旦mongo关闭,我得到以下堆栈跟踪

org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:77)
org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2114)
org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:1904)
org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:1712)
org.springframework.data.mongodb.core.MongoTemplate.findById(MongoTemplate.java:636)
org.springframework.session.data.mongo.MongoOperationsSessionRepository.findSession(MongoOperationsSessionRepository.java:127)
org.springframework.session.data.mongo.MongoOperationsSessionRepository.getSession(MongoOperationsSessionRepository.java:78)
org.springframework.session.data.mongo.MongoOperationsSessionRepository.getSession(MongoOperationsSessionRepository.java:44)
org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:326)
org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:343)
org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:214)
javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:255)
org.springframework.web.util.WebUtils.getSessionId(WebUtils.java:288)
org.springframework.web.servlet.FrameworkServlet.publishRequestHandledEvent(FrameworkServlet.java:1077)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:164)
org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:112)
org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:64)
org.springframework.boot.web.support.ErrorPageFilter.forwardToErrorPage(ErrorPageFilter.java:187)
org.springframework.boot.web.support.ErrorPageFilter.handleException(ErrorPageFilter.java:170)
org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:134)
org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:94)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:112)
org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)

JBWEB000071:根本原因

com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=STANDALONE, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused: connect}}]
    com.mongodb.connection.BaseCluster.createTimeoutException(BaseCluster.java:369)
    com.mongodb.connection.BaseCluster.selectServer(BaseCluster.java:101)
    com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:75)
    com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:71)
    com.mongodb.binding.ClusterBinding.getReadConnectionSource(ClusterBinding.java:63)
    com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:210)
    com.mongodb.operation.FindOperation.execute(FindOperation.java:482)
    com.mongodb.operation.FindOperation.execute(FindOperation.java:79)
    com.mongodb.Mongo.execute(Mongo.java:772)
    com.mongodb.Mongo$2.execute(Mongo.java:759)
    com.mongodb.DBCollection.findOne(DBCollection.java:777)
    com.mongodb.DBCollection.findOne(DBCollection.java:747)
    com.mongodb.DBCollection.findOne(DBCollection.java:694)
    org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java:2143)
    org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java:2127)
    org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:1901)
    org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:1712)
    org.springframework.data.mongodb.core.MongoTemplate.findById(MongoTemplate.java:636)
    org.springframework.session.data.mongo.MongoOperationsSessionRepository.findSession(MongoOperationsSessionRepository.java:127)
    org.springframework.session.data.mongo.MongoOperationsSessionRepository.getSession(MongoOperationsSessionRepository.java:78)
    org.springframework.session.data.mongo.MongoOperationsSessionRepository.getSession(MongoOperationsSessionRepository.java:44)
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:326)
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:343)
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:214)
    javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:255)
    org.springframework.web.util.WebUtils.getSessionId(WebUtils.java:288)
    org.springframework.web.servlet.FrameworkServlet.publishRequestHandledEvent(FrameworkServlet.java:1077)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:164)
    org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
    org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:112)
    org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:64)
    org.springframework.boot.web.support.ErrorPageFilter.forwardToErrorPage(ErrorPageFilter.java:187)
    org.springframework.boot.web.support.ErrorPageFilter.handleException(ErrorPageFilter.java:170)
    org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:134)
    org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
    org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:94)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:112)
    org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)

对于每个控制器,我都会获得此堆栈跟踪。我想优雅地处理这件事。请建议在应用程序启动后我应该在什么时候处理mongo连接异常。我正在为我的项目使用spring-boot-starter-data-mongodb maven依赖

1 个答案:

答案 0 :(得分:0)

SessionRepositoryFilter http://docs.spring.io/spring-session/docs/current/api/org/ ...由@EnableMongoHttpSession添加的代码是此处失败的代码。它在任何与控制器相关的机器(包括建议)可能发挥作用之前执行,因此如果失败,它将在创建任何控制器范围之前执行。

但是您可以创建一个过滤器,在Mongo Http Session过滤器之前将其插入到过滤器链中并尝试捕获并处理该异常:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    try {
        chain.doFilter(request, response);
    } catch (TranslatedException e) {
        // somehow handle it, like display an error message
    }
}

其中TranslatedException是弹簧翻译MongoTimeoutException的例外(从堆栈跟踪中看不到)。