您的位置:首页 > 运维架构 > Tomcat

《how tomcat work》 搬运工 Chapter 13: Host and Engine

2015-10-18 11:06 543 查看
Host和Engine是container的其中一种。

如果想要tomcat能够包含多个网站,则需要Host来包含多个context。

1.Host

The Host 接口

public interface Host extends Container {
public static final String ADD_ALIAS_EVENT = "addAlias";

public static final String REMOVE_ALIAS_EVENT = "removeAlias";

/**    * Return the application root for this Host.    * This can be an absolute    * pathname, a relative pathname, or a URL.    */
public String getAppBase();

/**    * Set the application root for this Host.  This can be an absolute    * pathname, a relative pathname, or a URL.    *    * @param appBase The new application root    */
public void setAppBase(String appBase);

/**    * Return the value of the auto deploy flag.    * If true, it indicates that    * this host's child webapps should be discovred and automatically    * deployed.    */
public boolean getAutoDeploy();

/**    * Set the auto deploy flag value for this host.    *    * @param autoDeploy The new auto deploy flag    */
public void setAutoDeploy(boolean autoDeploy);

/**    * Set the DefaultContext    * for new web applications.    *    * @param defaultContext The new DefaultContext    */
public void addDefaultContext(DefaultContext defaultContext);

/**    * Retrieve the DefaultContext for new web applications.    */
public DefaultContext getDefaultContext();

/**    * Return the canonical, fully qualified, name of the virtual host    * this Container represents.    */
public String getName();

/**    * Set the canonical, fully qualified, name of the virtual host    * this Container represents.    *    * @param name Virtual host name    *    * @exception IllegalArgumentException if name is null    */
public void setName(String name);

/**    * Import the DefaultContext config into a web application context.    *    * @param context web application context to import default context    */
public void importDefaultContext(Context context);

/**    * Add an alias name that should be mapped to this same Host.    *    * @param alias The alias to be added    */
public void addAlias(String alias);

/**    * Return the set of alias names for this Host.  If none are defined,    * a zero length array is returned.    */
public String[] findAliases();

/**    * Return the Context that would be used to process the specified    * host-relative request URI, if any;
otherwise return    * <code>null</code>.    *    * @param uri Request URI to be mapped    */
public Context map(String uri);

/**    * Remove the specified alias name from the aliases for this Host.    * @param alias Alias name to be removed    */
public void removeAlias(String alias);
}


StandardHost

像 StandardContext 和the StandardWrapper classes一样,standardHost在构造函数中添加StandardHostValve到pipeline中。每接受一个请求,standardHost都会触发它的基类baseContainer的invoke方法,而当pipeline触发到standardHostValue的invoke方法时,会通过host的map方法来查找正确的context。

public Context map(String uri) {
if (debug > 0)
log("Mapping request URI '" + uri + "'");
if (uri == null)
return (null);

// Match on the longest possible context path prefix
if (debug > 1)
log("  Trying the longest context path prefix");
Context context = null;
String mapuri = uri;
while (true) {
context = (Context) findChild(mapuri);
if (context != null)       break;
int slash = mapuri.lastIndexOf('/');
if (slash < 0)       break;
mapuri = mapuri.substring(0, slash);
}
// If no Context matches, select the default Context
if (context == null) {
if (debug > 1)
log("  Trying the default context");
context = (Context) findChild("");
}
// Complain if no Context has been selected
if (context == null) {
log(sm.getString("standardHost.mappingError", uri));
return (null);
}
// Return the mapped Context (if any)
if (debug > 0)
log(" Mapped to context '" + context.getPath() + "'");
return (context);
}


StandardHostMapper

在ContaninerBase类中,会在start()方法调用addDefaultMapper()方法来新建一个defaulet mapper,而在standardHost中会添加一个StandardHostMapper,而StandardHostMapper也是继承ContainerBase的,所以StandardHostMapper里的map方法是调用Host的map方法。

StandardHostValve

作为pipeline的basevalue,standardHostValve的作用就是查找适当的context处理请求,查看是否有session,更新session的时间限制。

public void invoke(Request request, Response response,   ValveContext valveContext)   throws IOException, ServletException {
// Validate the request and response object types
if (!(request.getRequest() instanceof HttpServletRequest) || !(response.getResponse() instanceof HttpServletResponse)) {
return;
// NOTE - Not much else we can do generically
}
// Select the Context to be used for this Request
StandardHost host = (StandardHost) getContainer();
Context context = (Context) host.map(request, true);
if (context == null) {
((HttpServletResponse) response.getResponse()).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
sm.getstring("StandardHost.noContext"));
return;
}
// Bind the context CL to the current thread
Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());

// Update the session last access time for our session (if any)
HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
String sessionId = hreq.getRequestedSessionId();
if (sessionId != null) {
Manager manager = context.getManager();
if (manager != null) {
Session session = manager.findSession(sessionId);
if ((session != null) && session.isValid())
session.access();
}
}
// Ask this Context to process this request   context.invoke(request, response);
}


2.Engine

Engine就代表了整个 Catalina servlet,你使用Engine就可以用多个host

The Engine 接口

public interface Engine extends Container {
/**    * Return the default hostname for this Engine.    */
public String getDefaultHost();

/**    * Set the default hostname for this Engine.    *    * @param defaultHost The new default host    */
public void setDefaultHost(String defaultHost);

/**    * Retrieve the JvmRouteId for this engine.    */
public String getJvmRoute();

/**    * Set the JvmRouteId for this engine.
*    * @param jvmRouteId the (new) JVM Route ID. Each Engine within a    * cluster must have a unique JVM Route ID.    */
public void setJvmRoute(String jvmRouteId);

/**    * Return the <code>Service</code> with which we are associated (if    * any).    */
public Service getService();

/**    * Set the <code>Service</code> with which we are associated (if    * any).    *    * @param service The service that owns this Engine    */
public void setService(Service service);

/**    * Set the DefaultContext    * for new web applications.    *    * @param defaultContext The new DefaultContext    */
public void addDefaultContext(DefaultContext defaultContext);

/**    * Retrieve the DefaultContext for new web applications.    */
public DefaultContext getDefaultContext();

/**    * Import the DefaultContext config into a web application context.    *    * @param context web application context to import default context    */
public void importDefaultContext(Context context);
}


StandardEngineValve

这个和standardHostValve差不多,查找正确的Host来处理请求

public void invoke(Request request, Response response,ValveContext valveContext) throws IOException, ServletException {
// Validate the request and response object types
if (!(request.getRequest() instanceof HttpServletRequest) || !(response.getResponse() instanceof HttpServletResponse)) {
return;
// NOTE - Not much else we can do generically
}
// Validate that any HTTP/1.1 request included a host header   HttpServletRequest hrequest = (HttpServletRequest) request;
if ("HTTP/1.1".equals(hrequest.getProtocol()) &&     (hrequest.getServerName() == null)) {
((HttpServletResponse)response.getResponse()).sendError(HttpServletResponse.SC_BAD_REQUEST,sm.getString("standardEngine.noHostHeader", request.getRequest().getServerName()));
return;
}
// Select the Host to be used for this Request
StandardEngine engine = (StandardEngine) getContainer();
Host host = (Host) engine.map(request, true);
if (host == null) {
((HttpServletResponse) response.getResponse()).sendError(HttpServletResponse.SC_BAD_REQUEST,sm.getString("standardEngine.noHost",request.getRequest().getServerName()));
return;
}
// Ask this Host to process this request
host.invoke(request, response);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: