In order to change this behavior we need to intercept the http status code 404, and modify the default redirection to redirect to a specified page. The best way to do that is to write a servlet filter and a wrapper for the servlet response.
- The servlet filter:
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
/**
*
* This is the servlet filter that wrap the servlet response object
* and use it in the FilterChain
* The wrapper will store the status code and do the re-direct if necessary
*/
public class Redirect404 implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(javax.servlet.ServletRequest request,
javax.servlet.ServletResponse response,
javax.servlet.FilterChain chain)
throws java.io.IOException, javax.servlet.ServletException{
HttpStatusServletResponse statusResponse =
new HttpStatusServletResponse((HttpServletResponse) response);
chain.doFilter(request, statusResponse);
int status = statusResponse.getStatus();
System.out.println("******** Status: " + status);
}
public void init(FilterConfig arg0) throws ServletException {
}
}
- The servlet response wrapper
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
*
* This is a wrapper class which is used to store the HTTP Status Code and modify the redirect.
*
*/
public class HttpStatusServletResponse extends HttpServletResponseWrapper {
private int httpStatus;
public HttpStatusServletResponse(HttpServletResponse response) {
super(response);
}
@Override
public void sendError(int sc) throws IOException {
httpStatus = sc;
super.sendError(sc);
}
@Override
public void sendError(int sc, String msg) throws IOException {
httpStatus = sc;
super.sendError(sc, msg);
}
@Override
public void sendRedirect(String location) throws IOException {
System.out.println("******* Calling sendRedirect, location is: " + location);
if (httpStatus == SC_NOT_FOUND)
location = "/wps/portal/404Error";
super.sendRedirect(location);
}
@Override
public void setStatus(int sc) {
httpStatus = sc;
super.setStatus(sc);
}
@Override
public void flushBuffer() throws java.io.IOException {
super.flushBuffer();
}
public int getStatus() {
return httpStatus;
}
}
We also need to modify the web.xml of wps.war, to add the filter definition and filter mapping. The following is the definition:
<filter>
<filter-name>Error 404 Redirect</filter-name>
<filter-class>com.servletFilter.Redirect404</filter-class>
</filter>
<filter-mapping>
<filter-name>Error 404 Redirect</filter-name>
<url-pattern>/portal/*</url-pattern>
</filter-mapping>
To update web.xml, you will need to export wps.ear (using wsadmin.sh|bat), expand wps.ear (using EARExpander.sh|bat), update web.xml (located at wps.war/WEB-INF), collapse back the wps.ear (using EARExpander.sh|bat), and install the new wps.ear back to portal server (using wsadmin.sh). The detailed instruction can be found in the following reference: How to redirect to a custom error page when HTTP 404 Not Found encountered on Non-URL Resources ("Resolving the problem" section).
References: