I have 2 applications/projects deployed in tomcat 7 web server. There context paths are different like "project1", "project2". When I hit URLs with these context path, corresponding application loads and works fine.
Valid URLs are:
http://localhost:8080/project1
http://localhost:8080/project2
Now when I hit any wrong URL with correct host name and incorrect context path like /project3, it give me error message 404 not found and shows a weird screen to the user.
I want to show a proper page with proper message to the end user. How can I do that in web server level?
You can adapt Tomcat's conf/web.xml
file to show some other page than the default for the 404 error - see here for an example.
Extract:
<error-page>
<error-code>404</error-code>
<location>/NotFound.jsp</location>
</error-page>
In theory, you should be able to modify the web.xml of the default tomcat web application, but according to this, that doesn't work for Tomcat 7.
Your other option is to extend the standard ErrorReportValve
. I have "borrowed" very liberally from the existing ErrorReportValve
code:
public class Custom404Valve extends ErrorReportValve{
public void invoke(Request request, Response response) throws IOException, ServletException {
if(request.getStatusCode() != 404){
super.invoke();
return;
}
// Perform the request
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);
//this is where your code really matters
//everything prior are just precautions I lifted
//from the stock valve.
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();
}
}
All you now need do is configure the custom valve:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Valve className="com.foo.bar.Custom404Valve"/>
</Host>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With