//
// ========================================================================
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.handler;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
AbstractHandler.
A convenience implementation of Handler
that uses the ContainerLifeCycle
to provide:
/**
* AbstractHandler.
* <p>A convenience implementation of {@link Handler} that uses the
* {@link ContainerLifeCycle} to provide:<ul>
* <li>start/stop behavior
* <li>a bean container
* <li>basic {@link Dumpable} support
* <li>a {@link Server} reference
* <li>optional error dispatch handling
* </ul>
*/
@ManagedObject("Jetty Handler")
public abstract class AbstractHandler extends ContainerLifeCycle implements Handler
{
private static final Logger LOG = Log.getLogger(AbstractHandler.class);
private Server _server;
/**
*
*/
public AbstractHandler()
{
}
@Override
public abstract void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
Convenience method to generate error page.
This method can be called from handle(String, Request, HttpServletRequest, HttpServletResponse)
when an DispatcherType.ERROR
dispatch is detected and an error page needs to be generated by calling HttpServletResponse.sendError(int, String)
with the appropriate code and reason, which are taken from ServletRequest.getAttribute(String)
for RequestDispatcher.ERROR_STATUS_CODE
and RequestDispatcher.ERROR_MESSAGE
Params: - target – The target of the request - either a URI or a name.
- baseRequest – The original unwrapped request object.
- request – The request either as the
Request
object or a wrapper of that request. The HttpConnection.getCurrentConnection()
.getHttpChannel()
.getRequest()
method can be used access the Request object if required. - response – The response as the
Response
object or a wrapper of that request. The HttpConnection.getCurrentConnection()
.getHttpChannel()
.getResponse()
method can be used access the Response object if required.
Throws: - IOException – if unable to handle the request or response processing
- ServletException – if unable to handle the request or response due to underlying servlet issue
See Also:
/**
* Convenience method to generate error page.
* <p>This method can be called from {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} when an {@link DispatcherType#ERROR} dispatch
* is detected and an error page needs to be generated by calling {@link HttpServletResponse#sendError(int, String)} with the appropriate code and reason,
* which are taken from {@link HttpServletRequest#getAttribute(String)} for {@link RequestDispatcher#ERROR_STATUS_CODE} and {@link RequestDispatcher#ERROR_MESSAGE}
*
* @param target The target of the request - either a URI or a name.
* @param baseRequest The original unwrapped request object.
* @param request The request either as the {@link Request} object or a wrapper of that request. The
* <code>{@link HttpConnection#getCurrentConnection()}.{@link HttpConnection#getHttpChannel() getHttpChannel()}.{@link HttpChannel#getRequest() getRequest()}</code>
* method can be used access the Request object if required.
* @param response The response as the {@link Response} object or a wrapper of that request. The
* <code>{@link HttpConnection#getCurrentConnection()}.{@link HttpConnection#getHttpChannel() getHttpChannel()}.{@link HttpChannel#getResponse() getResponse()}</code>
* method can be used access the Response object if required.
* @throws IOException if unable to handle the request or response processing
* @throws ServletException if unable to handle the request or response due to underlying servlet issue
* @see ErrorDispatchHandler for a convenience class that calls this method.
*/
protected void doError(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
Object o = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
int code = (o instanceof Integer) ? ((Integer)o).intValue() : (o != null ? Integer.parseInt(o.toString()) : 500);
o = request.getAttribute(RequestDispatcher.ERROR_MESSAGE);
String reason = o != null ? o.toString() : null;
response.sendError(code, reason);
}
/*
* @see org.eclipse.thread.LifeCycle#start()
*/
@Override
protected void doStart() throws Exception
{
if (LOG.isDebugEnabled())
LOG.debug("starting {}", this);
if (_server == null)
LOG.warn("No Server set for {}", this);
super.doStart();
}
/*
* @see org.eclipse.thread.LifeCycle#stop()
*/
@Override
protected void doStop() throws Exception
{
if (LOG.isDebugEnabled())
LOG.debug("stopping {}", this);
super.doStop();
}
@Override
public void setServer(Server server)
{
if (_server == server)
return;
if (isStarted())
throw new IllegalStateException(STARTED);
_server = server;
}
@Override
public Server getServer()
{
return _server;
}
@Override
public void destroy()
{
if (!isStopped())
throw new IllegalStateException("!STOPPED");
super.destroy();
}
An extension of AbstractHandler that handles DispatcherType.ERROR
dispatches. DispatcherType.ERROR
dispatches are handled by calling the AbstractHandler.doError(String, Request, HttpServletRequest, HttpServletResponse)
method. All other dispatches are passed to the abstract doNonErrorHandle(String, Request, HttpServletRequest, HttpServletResponse)
method, which should be implemented with specific handler behavior
/**
* An extension of AbstractHandler that handles {@link DispatcherType#ERROR} dispatches.
* <p>
* {@link DispatcherType#ERROR} dispatches are handled by calling the {@link #doError(String, Request, HttpServletRequest, HttpServletResponse)}
* method. All other dispatches are passed to the abstract {@link #doNonErrorHandle(String, Request, HttpServletRequest, HttpServletResponse)}
* method, which should be implemented with specific handler behavior
*/
public abstract static class ErrorDispatchHandler extends AbstractHandler
{
@Override
public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if (baseRequest.getDispatcherType() == DispatcherType.ERROR)
doError(target, baseRequest, request, response);
else
doNonErrorHandle(target, baseRequest, request, response);
}
Called by handle(String, Request, HttpServletRequest, HttpServletResponse)
for all non-DispatcherType.ERROR
dispatches. Params: - target – The target of the request - either a URI or a name.
- baseRequest – The original unwrapped request object.
- request – The request either as the
Request
object or a wrapper of that request. The HttpConnection.getCurrentConnection()
.getHttpChannel()
.getRequest()
method can be used access the Request object if required. - response – The response as the
Response
object or a wrapper of that request. The HttpConnection.getCurrentConnection()
.getHttpChannel()
.getResponse()
method can be used access the Response object if required.
Throws: - IOException – if unable to handle the request or response processing
- ServletException – if unable to handle the request or response due to underlying servlet issue
/**
* Called by {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)}
* for all non-{@link DispatcherType#ERROR} dispatches.
*
* @param target The target of the request - either a URI or a name.
* @param baseRequest The original unwrapped request object.
* @param request The request either as the {@link Request} object or a wrapper of that request. The
* <code>{@link HttpConnection#getCurrentConnection()}.{@link HttpConnection#getHttpChannel() getHttpChannel()}.{@link HttpChannel#getRequest() getRequest()}</code>
* method can be used access the Request object if required.
* @param response The response as the {@link Response} object or a wrapper of that request. The
* <code>{@link HttpConnection#getCurrentConnection()}.{@link HttpConnection#getHttpChannel() getHttpChannel()}.{@link HttpChannel#getResponse() getResponse()}</code>
* method can be used access the Response object if required.
* @throws IOException if unable to handle the request or response processing
* @throws ServletException if unable to handle the request or response due to underlying servlet issue
*/
protected abstract void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
}
}