A customized content can be returned to a Web client when a servlet generates an error. We can do that by adding <error-page /> elements in web.xml
The following table describes the elements we can use within an <error-page/> element.
Element |
Required/ Optional |
Description |
<error-code> |
Optional |
A valid HTTP error code, for example, 500 |
<exception-type> |
Optional |
A fully-qualified class name of a Java exception type, for example, java.lang.RuntimeException |
<location> |
Required |
The location of the resource to display in response to the error. For example, /myErrorPage.html . The location can be a Servlet or a JSP page as well. |
When an error occurs, <error-code> and <exception-type> are matched against the current error. On finding a match the request is redirected to the destination defined by <location>.
Request attributes related to error information
If the destination <location> is a servlet or a JSP page:
The original request and response objects are passed to the destination.
The request path and attributes are set as if a RequestDispatcher.forward to the error resource had been performed.
The request attributes are set with the followings.
Request Attributes |
Type |
javax.servlet.error.status_code |
java.lang.Integer |
javax.servlet.error.exception_type |
java.lang.Class |
javax.servlet.error.message |
java.lang.String |
javax.servlet.error.exception |
java.lang.Throwable |
javax.servlet.error.request_uri |
java.lang.String |
javax.servlet.error.servlet_name |
java.lang.String |
Types of error a Servlet/Filter can throw
A servlet or filter may throw the following exceptions during processing of a request:
- Unchecked exceptions i.e. RuntimeException, Error and subclasses
- ServletException or subclasses
- IOExceptions or subclasses
All other exception should be wrapped in ServletException
Examples
Mapping error to a servlet
<web-app ...>
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/errorHandler</location>
</error-page>
.......
</web-app>
@WebServlet(name = "errorHandlerServlet",
urlPatterns = {"/errorHandler"},
loadOnStartup = 1)
public class ErrorHandlerServlet extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
Exception exception = (Exception) req.getAttribute(
"javax.servlet.error.exception");
writer.printf("exception: %s%n", exception);
Class exceptionClass = (Class) req.getAttribute(
"javax.servlet.error.exception_type");
writer.printf("exception_type: %s%n", exceptionClass);
Integer code = (Integer) req.getAttribute(
"javax.servlet.error.status_code");
writer.printf("status_code: %s%n", code);
String errorMessage = (String) req.getAttribute(
"javax.servlet.error.message");
writer.printf("message: %s%n", errorMessage);
String requestUri = (String) req.getAttribute(
"javax.servlet.error.request_uri");
resp.getWriter().printf("request_uri: %s%n",
requestUri);
String servletName = (String) req.getAttribute(
"javax.servlet.error.servlet_name");
writer.printf("servlet_name: %s%n", servletName);
}
}
In above code, we can use constants like RequestDispatcher.ERROR_EXCEPTION instead of string literals.
Test servlet
@WebServlet(name = "testServlet",
urlPatterns = {"/test"},
loadOnStartup = 1)
public class TestServlet extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
int i = 1 / 0;
}
}
Run the embedded tomcat plugin:
mvn clean install tomcat7:run-war
Output
Mapping error to JSP
<web-app ...>
...
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/WEB-INF/jsps/exception.jsp</location>
</error-page>
...
</web-app>
src/main/webapp/WEB-INF/jsps/exception.jsp
<h3>Error on server side</h3>
<b>
<%= request.getAttribute("javax.servlet.error.exception") %>
</b>
Test servlet
@WebServlet(name = "testServlet2",
urlPatterns = {"/test2"},
loadOnStartup = 1)
public class TestServlet2 extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
throw new RuntimeException("test exception");
}
}
Output
Mapping error to HTML page
<web-app ...>
....
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/pages/custom-not-found-page.html</location>
</error-page>
.....
</web-app>
src/main/webapp/WEB-INF/pages/default-error-page.html
<html>
<body>
<p>Oops!! looks like there's nothing available at this location: <b>
<script>document.write(window.location.href)</script></b>
</p>
</body>
</html>
Output
Default error page
If an error-page element in the deployment descriptor does not contain an exception-type or an error-code element, the error page is a default error page:
<web-app ...>
....
<error-page>
<location>/WEB-INF/pages/default-error-page.html</location>
</error-page>
</web-app>
src/main/webapp/WEB-INF/pages/default-error-page.html
<html>
<body>
An unknown error occurred.
</body>
</html>
Test servlet
@WebServlet(name = "testServlet3",
urlPatterns = {"/test3"},
loadOnStartup = 1)
public class TestServlet3 extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
throw new ServletException();
}
}
Above servlet's error is not mapped to any error-page location in web.xml, so it will be directed to the default error page.
Output
Example Project
Dependencies and Technologies Used: - javax.servlet-api 3.1.0 Java Servlet API
- JDK 1.8
- Maven 3.3.9
|