Applications that do not use Spring MVC, ErrorPageRegistrar interface can be used to directly map errors.
Example
In this Servlet based example, we are going to create Servlets and will map errors with Boot's ErrorPageRegistrar .
An application Servlet
@WebServlet(name = "appServlet", urlPatterns = "/app/*")
public class MyAppServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String requestURI = req.getRequestURI();
if (requestURI.endsWith("test")) {
throw new RuntimeException("test exception from "+requestURI);
} else if (requestURI.endsWith("test2")) {
throw new ServletException("test servlet exception");
} else {
resp.getWriter().println("Response from appServlet at " + requestURI);
}
}
}
Implementing ErrorPageRegistrar
@Component
public class MyErrorPageRegistrar implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(
createNotFoundErrorPage(),
createRuntimeExceptionPage(),
createOtherErrorPage());
}
private ErrorPage createNotFoundErrorPage() {
return new ErrorPage(HttpStatus.NOT_FOUND, "/notFoundServlet");
}
private ErrorPage createRuntimeExceptionPage() {
return new ErrorPage(RuntimeException.class, "/runtimeExceptionHandler");
}
private ErrorPage createOtherErrorPage() {
return new ErrorPage(Throwable.class, "/WEB-INF/internal-error.jsp");
}
}
The Error Handler Servlets
@WebServlet(name = "not-found-error-servlet", urlPatterns = "/notFoundServlet")
public class NotFoundServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.write("<h2>Page not found </h2>");
String requestUri = (String) req.getAttribute("javax.servlet.error.request_uri");
writer.write("request uri: " + requestUri);
writer.write("<br>Response from "+this.getClass());
}
}
@WebServlet(name = "runtime-handler-servlet", urlPatterns = "/runtimeExceptionHandler")
public class RuntimeExceptionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.write("<h2>RuntimeException</h2>");
String requestUri = (String) req.getAttribute(RequestDispatcher.ERROR_REQUEST_URI);
writer.write("request uri: " + requestUri);
Integer code = (Integer) req.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
writer.write("<br>status code: " + code);
String errorMessage = (String) req.getAttribute(RequestDispatcher.ERROR_MESSAGE);
writer.write("<br>error message: " + errorMessage);
writer.write("<br>Response from "+this.getClass());
}
}
The JSP Page
/src/main/webapp/WEB-INF/internal-error.jsp<h3>Error on server side</h3>
<p>
<%= request.getAttribute("javax.servlet.error.exception") %>
</p>
<p>From jsp page.</p>
Boot main class
@SpringBootApplication
@ServletComponentScan
public class SpringBootMain extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure (SpringApplicationBuilder builder) {
return builder.sources(SpringBootMain.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class);
}
}
Check out this tutorial to understand why @ServletComponentScan is needed in above class.
Output
To try examples, run spring-boot maven plugin (configured in pom.xml of example project below):
mvn spring-boot:run
The above example application will also work, if we deploy it to a server or execute it as a war.
Also check out how to map errors in a Servlet application without Boot.
Example ProjectDependencies and Technologies Used: - Spring Boot 2.0.0.RELEASE
Corresponding Spring Version 5.0.4.RELEASE - spring-boot-starter-web : Starter for building web, including RESTful, applications using Spring
MVC. Uses Tomcat as the default embedded container.
- spring-boot-starter-tomcat : Starter for using Tomcat as the embedded servlet container. Default
servlet container starter used by spring-boot-starter-web.
- tomcat-embed-jasper 8.5.28: Core Tomcat implementation.
- jstl 1.2 javax.servlet:jstl
- JDK 1.8
- Maven 3.3.9
|