如何在不发送错误页面的情况下处理异常?如何为异常对象设置消息详细信息?(不使用任何JSTL标记)
谢谢, 拉维
答案 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仅用于表示逻辑。