数据库连接失败时如何重定向到错误页面?

Posted

技术标签:

【中文标题】数据库连接失败时如何重定向到错误页面?【英文标题】:How to redirect to an error page when database connection fails? 【发布时间】:2014-02-20 21:25:56 【问题描述】:

我正在尝试在我的应用程序中实现一个功能,例如,在对容器的第一次请求时,如果数据库无法连接,它应该重定向到错误页面而不是显示 index.jsp

    我有一个单例DBConnectionManager 类,它在构造函数中处理数据库连接,也是一个返回连接对象的方法。

    我有一个 servlet 上下文侦听器。所以当上下文初始化时,它会调用DBConnectionManager构造函数并初始化数据库连接。我将在我的所有模型 DAO 中检索并使用相同的连接对象。

现在我的问题是如何处理连接错误并将其从DBConnectionManager 或servlet 上下文侦听器重定向到error.jsp 页面。我应该在哪里放置重定向条件。

供参考: DBConnectionManager.java=>

public DBConnectionManager(String url,String user,String pass)

//constructor called by servlet context listener.
this.DBURL=url;
this.user=user;
this.pass=pass;
try 
Class.forName("com.mysql.jdbc.Driver");

catch (ClassNotFoundException e) 
log.info("Class Not Found :"+e);
return;

try 
log.info("-------url recieved :"+url);
log.info("-------username received :"+user);
log.info("--------password received :"+pass);
con = DriverManager.getConnection(url,user,pass);
log.info("con initialised..");
 
catch (SQLException e) 
//Exception caught here successfully.
log.info("Problem in connecting :"+e);
return;


if (con != null) 
log.info("Connected Successfully to database");
 else 
log.info("Mysql not connected.:<");


public Connection getConnection()

 //Method called in every DAOmodel to return the instance of the connection object.
 //Where DAO uses this connection object to query database.
return this.con;   

我的 Servlet 上下文监听器来了=>

public void contextInitialized(ServletContextEvent servletContextEvent) 
        ServletContext ctx=servletContextEvent.getServletContext();
        String url=ctx.getInitParameter("DBURL");
        String user=ctx.getInitParameter("DBUSER");
        String pass=ctx.getInitParameter("DBPWD");

        //Constructor called here
        DBConnectionManager dbManager= new DBConnectionManager(url,user,pass);
        log.info("printing db manager::"+dbManager);
        ctx.setAttribute("DBManager", dbManager);
        log.info("dbmanager Initialized");

        

public void contextDestroyed(ServletContextEvent servletContextEvent) 
        ServletContext ctx=servletContextEvent.getServletContext();
        DBConnectionManager dbManager=      (DBConnectionManager)ctx.getAttribute("DBManager");
        dbManager.closeConnection();
        log.info("dbmanager destroyed and database connection closed");

如果您对我的问题有任何疑问,希望这可以解决。

【问题讨论】:

【参考方案1】:

您可以在web.xmllike 中抛出异常并为此类错误定义 500 页;

<error-page>
    <error-code>500</error-code>
    <location>/error.html</location>
</error-page>

当您的系统出现错误时,error.html 将被渲染。对于其他类型的错误,你可以定义;

<error-page>
    <!-- Missing login -->
    <error-code>401</error-code>
    <location>/error-401.html</location>
</error-page>
<error-page>
    <!-- Forbidden directory listing -->
    <error-code>403</error-code>
    <location>/error-403.html</location>
</error-page>
<error-page>
    <!-- Uncaught exception -->
    <error-code>500</error-code>
    <location>/error-500.html</location>
</error-page>
<error-page>
    <!-- Unsupported servlet method -->
    <error-code>503</error-code>
    <location>/error-503.html</location>
</error-page>

【讨论】:

那将是基于 http 错误的错误。我的问题不同。 你的问题也是基于http的重定向,如果连接时抛出异常,这个结构将重定向你错误页面而不是index.jsp 如果我在 Servlet(Controller) 中有一个 dbconnection 和异常管理代码。我可以配置我的 web.xml 以重定向到某个错误页面。我在模型类下有这个。 好的,您可能在控制器中使用了该模型。如果您在模型上抛出异常,它将被错误页面处理程序捕获。【参考方案2】:

如果你想处理所有 db 异常,你需要把它作为一个 SomeDbException 抛出并添加到web.xml。也可以关注doc。

<error-page>
    <exception-type>SomeDbException</exception-type>
    <location>/error.html</location>
</error-page>

【讨论】:

如果 servlet 抛出异常,容器会在 web.xml 中查找配置。这里不涉及servlet。 DBConnectionManager 只是一个 java 类(模型)。 OK,但是 DBConnectionManager 是从 servlet 调用的,不是吗?因此,您将在DBConnectionManager 中抛出异常,而不是捕获它 enywere 或捕获它并重新抛出另一个异常,结果 servlet 容器会自动将其重定向到配置的页面。 我没有从任何 servlet 调用 DBConnectionManager。我从 ServletContextLister 调用它。 因此您可以在ServletContextListener 中处理异常,将信息添加到ServletContext 属性并在Filter 或Servlet 中读取此信息。见here 是的,但我认为最好在filter 中执行,不要将处理与servlet 逻辑合并。【参考方案3】:

@Prithviraj:答案如下:假设您有Index.jsp 页面,其中连接失败并且您遇到一些异常。 所以在那个页面(Index.jsp)中,你需要使用&lt;%@ page %&gt;指令的errorPage属性。像这样:&lt;%@ page errorPage="Error.jsp %&gt; 而在Error.jsp 页面中,您需要使用&lt;%@ page %&gt; 指令的isErrorPage 属性。 像这样:&lt;%@ page isErrorPage="true" %&gt;。 现在当连接失败并出现异常时会发生什么,然后自动控制将重定向到Error.jsp页面,您不必编写重定向逻辑。

相信会对你有所帮助。

【讨论】:

你能说得更具体一点吗?我需要从 index.jsp 页面重定向到 SQLException 上的 error.jsp 页面。如何让 index.jsp 监听 SQLException。 你不必担心,如果出现异常,控制将重定向到error.jsp页面。在 error.jsp 页面上,您将拥有内置的异常对象,因此对于异常类型,您可以使用异常对象。【参考方案4】:

无论哪种错误,您都可以随时重定向到任何其他页面:

<%
try 
    // do whatever you want (Connect to database ...)
 catch(Exception ex) 
    // logging ...

    response.sendRedirect(..);
    return;

%>

更新

对不起,我对你的问题有点困惑。但是:

如果在 servlet 初始化时发生错误并且您的单音类在其中,请留下此错误,因为应用程序无法启动,并且用户无论如何都应该修复它,您可以生成任何日志以帮助用户找出什么是问题所在! 对于实用程序和一些特殊情况,Singleton 还不错,但对于 Web 应用程序,您应该尽可能避免使用它。如果它对每个用户都是唯一的,您可以创建一个实例并将其放在会话中,如果它在整个系统中是唯一的,则可以将它放在 servlet 上下文中。 getServletContext().setAttribute("my", sample); 希望对您有所帮助

希望对你有帮助

【讨论】:

它不是一个 servlet 类。所以我没有使用响应或请求对象。它只是一个单例 java 类。那我怎么能使用 response.sendRedirect();

以上是关于数据库连接失败时如何重定向到错误页面?的主要内容,如果未能解决你的问题,请参考以下文章

如果发生数据库错误,如何将页面重定向到其他页面

使用 HTTPS 连接重定向响应

重定向后停止连接

检测浏览器是不是正在执行重定向

如何在 CURL 重定向上传递 cookie?

php:如何重定向到带有错误消息的同一页面