Exception Handling in Jsp
How 开发者_开发技巧will you handle the exception without sending to error page? How will you set a message detail to the exception object?(Not using any JSTL Tags)
Thanks, Ravi
I think the best answer is you don't.
It is considered good design with jsp technology to handle all the stuff that can cause exceptions before you start the render-phase. This means you should normally try to do things that can cause exceptions in "execute" methods in your web framework before arriving at the jsp page. If you need to catch anything, do it there.
Not using any JSTL Tags
I was going to suggest the c:catch
, but as you don't want to use JSTL, it stops here.
Still then, it would have been a bad idea. You normally really don't want to use JSP for business logic. Just use (indirectly) a Servlet for this. With Servlets you can control, preprocess and/or postprocess requests and forward the request to the JSP file which in turn displays the data using EL and controls the page flow dynamically using taglibs like <jsp:xxx>
and JSTL.
Here's a basic example based on the "login user" idea:
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);
}
and then the basic JSP example:
<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>
You could go further by using for example a Map<String, String>
for the messages so that you can attach an error message to every input field. You could go any further by using a MVC framework which takes all this work from your hands, but that's another story ;)
Most answers are right saying that most of the things which can trigger exceptions occur in the controller in a MVC setup and should be handled there.
But still - exceptions in JSP happen. If you just say, they shouldn't happen it doesn't help at all.
JSP Exception handling is difficult because the JSP buffer is flushed from time to time (default size is 8KB, but flushing occurs on each jsp:include too). If the buffer is flushed the response is committed. "committed" means the response is partially written to the client. So http headers and may be http body is already sent.
If the response is not committed the servlet container can forward
to the configured error-page.
If the response is already committed the servlet container can not easily handle the exception. Still tomcat tries to do so, if you configured an <error-page>
in your web.xml. At least tomcat tries to include instead of forward the error-page. This is usually bad and the output is completely garbage. If an exception occurs again or tomcat is unable to handle it might show a stack trace (depends on how you configured ErrorReportValve)
The only way to handle exceptions in JSP completely is a filter in my opinion:
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;
}
}
}
}
This way you buffer all of your jsp response. So you will be sure the original response is not committed by the time any exception occurs. You can as with throw e
throw the exception to bubble up. Tomcat then forwards to your error-page. But if you are already in the error dispatcher you just show an error page by yourself.
This way you will never see a stack trace with your tomcat engine.
A nice benefit is a proper gzip compression with your http Connector if you configured it with compression=on as the filter can compress the complete buffer at once. Otherwise not all chunks of data get compressed because they are to small.
Drawback might be more memory usage. But for us I watched the memory usage on a high traffic side and it didn't grow surprisingly.
Almost every web app is developed using MVC so that 90% of using java code in fore ground is reduced remaining 10% can achieve with JSTl tags of standard or custom tags and EL.
If not followed its bad idea to handle exception.Since jsp is meant for only presentation logic.
Refer to JSP Exception Handling
精彩评论