Valve that implements the default basic behavior for the
| Method from org.apache.catalina.core.StandardHostValve Detail: |
protected boolean custom(Request request,
Response response,
ErrorPage errorPage) {
if (container.getLogger().isDebugEnabled())
container.getLogger().debug("Processing " + errorPage);
request.setPathInfo(errorPage.getLocation());
try {
// Reset the response (keeping the real error code and message)
response.resetBuffer(true);
// Forward control to the specified location
ServletContext servletContext =
request.getContext().getServletContext();
RequestDispatcher rd =
servletContext.getRequestDispatcher(errorPage.getLocation());
rd.forward(request.getRequest(), response.getResponse());
// If we forward, the response is suspended again
response.setSuspended(false);
// Indicate that we have successfully processed this custom page
return (true);
} catch (Throwable t) {
// Report our failure to process this custom page
container.getLogger().error("Exception Processing " + errorPage, t);
return (false);
}
}
Handle an HTTP status code or Java exception by forwarding control
to the location included in the specified errorPage object. It is
assumed that the caller has already recorded any request attributes
that are to be forwarded to this page. Return true if
we successfully utilized the specified error page location, or
false if the default error report should be rendered. |
public final void event(Request request,
Response response,
CometEvent event) throws IOException, ServletException {
// Select the Context to be used for this Request
Context context = request.getContext();
// Bind the context CL to the current thread
if( context.getLoader() != null ) {
// Not started - it should check for availability first
// This should eventually move to Engine, it's generic.
Thread.currentThread().setContextClassLoader
(context.getLoader().getClassLoader());
}
// Ask this Context to process this request
context.getPipeline().getFirst().event(request, response, event);
// Access a session (if present) to update last accessed time, based on a
// strict interpretation of the specification
if (Globals.STRICT_SERVLET_COMPLIANCE) {
request.getSession(false);
}
// Error page processing
response.setSuspended(false);
Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
if (t != null) {
throwable(request, response, t);
} else {
status(request, response);
}
// Restore the context classloader
Thread.currentThread().setContextClassLoader
(StandardHostValve.class.getClassLoader());
}
|
protected static ErrorPage findErrorPage(Context context,
Throwable exception) {
if (exception == null)
return (null);
Class< ? > clazz = exception.getClass();
String name = clazz.getName();
while (!Object.class.equals(clazz)) {
ErrorPage errorPage = context.findErrorPage(name);
if (errorPage != null)
return (errorPage);
clazz = clazz.getSuperclass();
if (clazz == null)
break;
name = clazz.getName();
}
return (null);
}
Find and return the ErrorPage instance for the specified exception's
class, or an ErrorPage instance for the closest superclass for which
there is such a definition. If no associated ErrorPage instance is
found, return null. |
public String getInfo() {
return (info);
}
Return descriptive information about this Valve implementation. |
public final void invoke(Request request,
Response response) throws IOException, ServletException {
// Select the Context to be used for this Request
Context context = request.getContext();
if (context == null) {
response.sendError
(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
sm.getString("standardHost.noContext"));
return;
}
// Bind the context CL to the current thread
if( context.getLoader() != null ) {
// Not started - it should check for availability first
// This should eventually move to Engine, it's generic.
Thread.currentThread().setContextClassLoader
(context.getLoader().getClassLoader());
}
// Ask this Context to process this request
context.getPipeline().getFirst().invoke(request, response);
// Access a session (if present) to update last accessed time, based on a
// strict interpretation of the specification
if (Globals.STRICT_SERVLET_COMPLIANCE) {
request.getSession(false);
}
// Error page processing
response.setSuspended(false);
Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);
if (t != null) {
throwable(request, response, t);
} else {
status(request, response);
}
// Restore the context classloader
Thread.currentThread().setContextClassLoader
(StandardHostValve.class.getClassLoader());
}
Select the appropriate child Context to process this request,
based on the specified request URI. If no matching Context can
be found, return an appropriate HTTP error. |
protected void status(Request request,
Response response) {
int statusCode = response.getStatus();
// Handle a custom error page for this status code
Context context = request.getContext();
if (context == null)
return;
/* Only look for error pages when isError() is set.
* isError() is set when response.sendError() is invoked. This
* allows custom error pages without relying on default from
* web.xml.
*/
if (!response.isError())
return;
ErrorPage errorPage = context.findErrorPage(statusCode);
if (errorPage != null) {
response.setAppCommitted(false);
request.setAttribute(Globals.STATUS_CODE_ATTR,
new Integer(statusCode));
String message = response.getMessage();
if (message == null)
message = "";
request.setAttribute(Globals.ERROR_MESSAGE_ATTR, message);
request.setAttribute
(ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
errorPage.getLocation());
request.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
new Integer(ApplicationFilterFactory.ERROR));
Wrapper wrapper = request.getWrapper();
if (wrapper != null)
request.setAttribute(Globals.SERVLET_NAME_ATTR,
wrapper.getName());
request.setAttribute(Globals.EXCEPTION_PAGE_ATTR,
request.getRequestURI());
if (custom(request, response, errorPage)) {
try {
response.flushBuffer();
} catch (ClientAbortException e) {
// Ignore
} catch (IOException e) {
container.getLogger().warn("Exception Processing " + errorPage, e);
}
}
}
}
Handle the HTTP status code (and corresponding message) generated
while processing the specified Request to produce the specified
Response. Any exceptions that occur during generation of the error
report are logged and swallowed. |
protected void throwable(Request request,
Response response,
Throwable throwable) {
Context context = request.getContext();
if (context == null)
return;
Throwable realError = throwable;
if (realError instanceof ServletException) {
realError = ((ServletException) realError).getRootCause();
if (realError == null) {
realError = throwable;
}
}
// If this is an aborted request from a client just log it and return
if (realError instanceof ClientAbortException ) {
if (log.isDebugEnabled()) {
log.debug
(sm.getString("standardHost.clientAbort",
realError.getCause().getMessage()));
}
return;
}
ErrorPage errorPage = findErrorPage(context, throwable);
if ((errorPage == null) && (realError != throwable)) {
errorPage = findErrorPage(context, realError);
}
if (errorPage != null) {
response.setAppCommitted(false);
request.setAttribute
(ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
errorPage.getLocation());
request.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
new Integer(ApplicationFilterFactory.ERROR));
request.setAttribute
(Globals.STATUS_CODE_ATTR,
new Integer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
request.setAttribute(Globals.ERROR_MESSAGE_ATTR,
throwable.getMessage());
request.setAttribute(Globals.EXCEPTION_ATTR,
realError);
Wrapper wrapper = request.getWrapper();
if (wrapper != null)
request.setAttribute(Globals.SERVLET_NAME_ATTR,
wrapper.getName());
request.setAttribute(Globals.EXCEPTION_PAGE_ATTR,
request.getRequestURI());
request.setAttribute(Globals.EXCEPTION_TYPE_ATTR,
realError.getClass());
if (custom(request, response, errorPage)) {
try {
response.flushBuffer();
} catch (IOException e) {
container.getLogger().warn("Exception Processing " + errorPage, e);
}
}
} else {
// A custom error-page has not been defined for the exception
// that was thrown during request processing. Check if an
// error-page for error code 500 was specified and if so,
// send that page back as the response.
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
// The response is an error
response.setError();
status(request, response);
}
}
Handle the specified Throwable encountered while processing
the specified Request to produce the specified Response. Any
exceptions that occur during generation of the exception report are
logged and swallowed. |