Jsp中的异常处理

时间:2010-01-11 19:06:05

标签: jsp

如何在不发送错误页面的情况下处理异常?如何为异常对象设置消息详细信息?(不使用任何JSTL标记)

谢谢, 拉维

4 个答案:

答案 0 :(得分:2)

我认为最好的答案是你没有。

在启动渲染阶段之前,jsp技术被认为是处理所有可能导致异常的东西的好设计。这意味着您应该在到达jsp页面之前尝试做一些可能导致Web框架中“execute”方法异常的事情。如果你需要捕捉任何东西,那就去做吧。

答案 1 :(得分:1)

  

不使用任何JSTL标记

我打算建议c:catch,但由于你不想使用JSTL,它会停在这里。

然而,这仍然是一个坏主意。您通常不希望将JSP用于业务逻辑。只需使用(间接)Servlet即可。使用Servlet,您可以控制,预处理和/或后处理请求,并将请求转发到JSP文件,然后使用EL显示数据,并使用<jsp:xxx>和{{3}等标记库动态控制页面流}}

以下是基于“登录用户”理念的基本示例:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
        request.setAttribute("error", "Please enter both username and password.");
    } else {
        User user = userDAO.find(username, password);
        if (user == null) {
            request.setAttribute("error", "Unknown login, please try again.");
        } else {
            request.getSession().setAttribute("user", user);
            request.setAttribute("succes", "Login succesful!");
        }
    }

    request.getRequestDispatcher("login.jsp").forward(request, response);
}

然后是基本的JSP示例:

<form action="login" method="post">
     Username: <input type="text" name="username" value="${param.username}"><br>
     Password: <input type="password" name="password" value="${param.password}"><br>
     Login: <input type="submit" value="Login"><br>
     <span class="error">${error}</span>
     <span class="succes">${succes}</span>
</form>

您可以使用例如Map<String, String>作为消息,以便您可以将错误消息附加到每个输入字段。您可以通过使用MVC框架进一步完成,这个框架可以完成所有这些工作,但这是另一个故事;)

答案 2 :(得分:1)

大多数答案都是正确的说,大多数可以触发异常的事情都发生在MVC设置的控制器中,应该在那里处理。

但仍然 - JSP中的异常发生。如果你只是说,他们不应该发生它根本没有帮助。

JSP异常处理很困难,因为JSP缓冲区不时被刷新(默认大小为8KB,但每个jsp上也会发生刷新:include)。如果刷新缓冲区,则提交响应。 &#34;致力于&#34;表示响应部分写入客户端。所以http标头可能已经发送了http正文。

如果未提交响应,则servlet容器可以forward到已配置的错误页面。

如果响应已经提交,则servlet容器无法轻松处理异常。如果您在web.xml中配置了<error-page>,那么tomcat仍会尝试这样做。至少tomcat尝试包含而不是转发错误页面。这通常很糟糕,输出完全是垃圾。如果再次发生异常或者tomcat无法处理,则可能会显示堆栈跟踪(取决于您如何配置ErrorReportValve)

在我看来,完全处理JSP中异常的唯一方法是过滤器:

public class BufferingFilter extends AbstractHttpFilter
{
    private static final String FIX_HTML    = "<html><body>An error occured and even the error handling failed. This should not happen. We are going to fix it as soon as posssible.</body></html>";

    @Override
    protected void doHttpFilter ( HttpServletRequest request, HttpServletResponse response, FilterChain chain ) throws IOException, ServletException
    {
        BufferingResponse contentBufferingResponse = new BufferingResponse(response);
        try
        {
            chain.doFilter(request, contentBufferingResponse);
            OutputStream out = response.getOutputStream();
            out.write(contentBufferingResponse.getData());
            out.close();
        }
        catch (Exception e)
        {
            if (request.getDispatcherType().equals(DispatcherType.ERROR))
            {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.getWriter().append(FIX_HTML);
                response.flushBuffer();
            }
            else
            {
                throw e;
            }
        }
    }
}

这样可以缓冲所有jsp响应。因此,您将确保在发生任何异常时未提交原始响应。您可以像throw e一样抛出异常来冒泡。 Tomcat然后转发到您的错误页面。但是,如果您已经在错误调度程序中,则只需自己显示错误页面。

这样你就永远不会看到tomcat引擎的堆栈跟踪。

如果您使用compression = on配置了http连接器,则可以使用http连接器进行正确的gzip压缩,因为过滤器可以立即压缩整个缓冲区。否则,并非所有数据块都会被压缩,因为它们很小。

缺点可能是内存使用量增加。但是对于我们来说,我在高流量方面观察了内存的使用情况,但并没有令人惊讶地增长。

答案 3 :(得分:0)

几乎每个Web应用程序都是使用MVC开发的,因此使用标准或自定义标签和EL的JSTl标签可以减少90%的使用前置Java代码,其余10%可以实现。

如果没有遵循错误的想法来处理异常。因为jsp仅用于表示逻辑。

请参阅JSP Exception Handling