server:
type: simple
rootPath: /rest
applicationContextPath: /app
adminContextPath: /app/admin
connector:
type: http
port: 8084With this I am able to successfully create and server my REST resources off URL's like this:
http://<host>:8084/app/rest/<my-resource-name>
and my assets (i.e. html, css, js, images, etc) are served off URL's like this:
http://<host>:8084/app/path/to/asset/<asset-name>
where "path" cannot be "rest" as that is where my REST resources are served off.
My Dropwizard Application class overrides the initialize method and registers some bundles like so:
@Override
public void initialize(final Bootstrap<AppConfiguration> bootstrap)
{
bootstrap.addBundle(new AssetsBundle("/assets/", "/", "index.html", "assets"));
bootstrap.addBundle(new AssetsBundle("/node_modules/", "/node_modules/", null, "node_modules"));
...
}and also overrides the run method and registers my REST resources like so:
@Override
public void run(final AppConfiguration configuration, final Environment environment)
{
environment.jersey().register(new MyRestResource1());
environment.jersey().register(new MyRestResource2());
...
}The application itself is built using Maven which produces a shaded JAR.
My assets (i.e. html, css, js, images, etc), however, are not included in this shaded JAR. I have kept them separate and have modified my POM file accordingly by using the maven-jar-plugin to add the folder containing all my assets to the JAR file. For reference this is the POM section that does that:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>./path/to/where/my/assets/reside/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>Everything is working as expected.
Question
I now want to handle cases where the user either types a URL to an unknown REST request like:
http://<host>:8084/app/rest/some-unknown-REST-resource
or to an unknown asset like either of these:
http://<host>:8084/app/path/to/unknown-asset-folder/<asset-name>
http://<host>:8084/app/path/to/asset/<unknown-asset-name>
In the above cases I want to serve a custom 404 page.
What is the best way of achieving this?
What I've already tried
1. I have registered a custom RuntimeException ExceptionMapper in my applications run method.
This however only seems to kick-in on unknown REST resources. Trying to access unknown assets stills serves the default 404 page.
2. I tried creating a DefaultResource as described here: how-to-view-custom-404-page-in-dropwizard
but that did no seem to work.
3. I found this article: Jetty Custom Error Pages
and I really would like to use the first method described there that makes use of web.xml but am not sure how to use this with Dropwizard.
4. I tried looking in the Dropwizard configuration reference here: Reference
but could not find anything related to my requirements.
public class MyApplication extends Application<MyConfiguration> {
// ...
@Override
public void run(final MyConfiguration configuration, final Environment environment) {
// ...
final ErrorPageErrorHandler epeh = new ErrorPageErrorHandler();
// 400 - Bad Request, leave alone
epeh.addErrorPage(401, "/error/general-error");
epeh.addErrorPage(402, "/error/general-error");
epeh.addErrorPage(403, "/error/403");
epeh.addErrorPage(404, "/error/404");
epeh.addErrorPage(405, 499, "/error/general-error");
epeh.addErrorPage(500, 599, "/error/general-error");
environment.getApplicationContext().setErrorHandler(epeh);
// ...
}
}