In theory you should be able to change the web.xml tomcat web applications by default, but according to this , it does not work for Tomcat 7.
Another option is to expand the standard ErrorReportValve. I very much "borrowed" from the existing code ErrorReportValve:
public class Custom404Valve extends ErrorReportValve{
public void invoke(Request request, Response response) throws IOException, ServletException {
if(request.getStatusCode() != 404){
super.invoke();
return;
}
getNext().invoke(request, response);
if (response.isCommitted()) {
if (response.setErrorReported()) {
try {
response.flushBuffer();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
}
response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
}
return;
}
response.setSuspended(false);
try {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
String theErrorPage = loadErrorPage();
Writer writer = response.getReporter();
writer.write(theErrorPage);
response.finishResponse();
} catch (Throwable tt) {
ExceptionUtils.handleThrowable(tt);
}
if (request.isAsyncStarted()) {
request.getAsyncContext().complete();
}
}
protected String loadErrorPage() {
BufferedReader reader = null;
StringBuilder errorMessage = new StringBuilder();
try{
File file = new File("YourErrorPage.html");
reader = new BufferedReader(new FileReader(file));
while (reader.ready()) {
errorMessage.append(reader.readLine());
}
}catch (IOException e){
e.printStackTrace();
}finally{
try{
reader.close();
}catch (IOException e) {
e.printStackTrace();
}
}
return errorMessage.toString();
}
}
Now you need to configure a custom valve:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Valve className="com.foo.bar.Custom404Valve"/>
</Host>
source
share