Method from org.apache.catalina.startup.Tomcat Detail: |
public StandardContext addContext(String contextPath,
String baseDir) {
return addContext(getHost(), contextPath, baseDir);
}
Add a context - programmatic mode, no web.xml used.
API calls equivalent with web.xml:
context-param
ctx.addParameter("name", "value");
error-page
ErrorPage ep = new ErrorPage();
ep.setErrorCode(500);
ep.setLocation("/error.html");
ctx.addErrorPage(ep);
ctx.addMimeMapping("ext", "type");
TODO: add the rest |
public StandardContext addContext(StandardHost host,
String contextPath,
String dir) {
silence(contextPath);
StandardContext ctx = new StandardContext();
ctx.setPath( contextPath );
ctx.setDocBase(dir);
ctx.addLifecycleListener(new FixContextListener());
if (host == null) {
host = getHost();
}
host.addChild(ctx);
return ctx;
}
|
public void addRole(String user,
String role) {
List< String > roles = userRoles.get(user);
if (roles == null) {
roles = new ArrayList< String >();
userRoles.put(user, roles);
}
roles.add(role);
}
|
public StandardWrapper addServlet(String contextPath,
String servletName,
String servletClass) {
Container ctx = getHost().findChild(contextPath);
return addServlet((StandardContext) ctx,
servletName, servletClass);
}
|
public StandardWrapper addServlet(StandardContext ctx,
String servletName,
String servletClass) {
// will do class for name and set init params
StandardWrapper sw = (StandardWrapper)ctx.createWrapper();
sw.setServletClass(servletClass);
sw.setName(servletName);
ctx.addChild(sw);
return sw;
}
Equivalent with
.
In general it is better/faster to use the method that takes a
Servlet as param - this one can be used if the servlet is not
commonly used, and want to avoid loading all deps.
( for example: jsp servlet )
You can customize the returned servlet, ex:
wrapper.addInitParameter("name", "value"); |
public StandardWrapper addServlet(StandardContext ctx,
String servletName,
Servlet servlet) {
// will do class for name and set init params
StandardWrapper sw = new ExistingStandardWrapper(servlet);
sw.setName(servletName);
ctx.addChild(sw);
return sw;
}
Use an existing servlet, no class.forName or initialization will be
performed |
public void addUser(String user,
String pass) {
userPass.put(user, pass);
}
Add a user for the in-memory realm. All created apps use this
by default, can be replaced using setRealm(). |
public StandardContext addWebapp(String contextPath,
String baseDir) throws ServletException {
return addWebapp(getHost(), contextPath, baseDir);
}
Add a webapp using normal WEB-INF/web.xml if found. |
public StandardContext addWebapp(StandardHost host,
String url,
String path) throws ServletException {
silence(url);
StandardContext ctx = new StandardContext();
ctx.setPath( url );
ctx.setDocBase(path);
if (defaultRealm == null) {
initSimpleAuth();
}
ctx.setRealm(defaultRealm);
initWebappDefaults(ctx);
ContextConfig ctxCfg = new ContextConfig();
ctx.addLifecycleListener( ctxCfg );
// prevent it from looking ( if it finds one - it'll have dup error )
ctxCfg.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML");
if (host == null) {
host = getHost();
}
host.addChild(ctx);
return ctx;
}
|
public Connector getConnector() throws Exception {
getServer();
if (connector != null) {
return connector;
}
// This will load Apr connector if available,
// default to nio. I'm having strange problems with apr
// and for the use case the speed benefit wouldn't matter.
//connector = new Connector("HTTP/1.1");
connector = new Connector("org.apache.coyote.http11.Http11Protocol");
connector.setPort(port);
service.addConnector( connector );
return connector;
}
Get the default http connector. You can set more
parameters - the port is already initialized.
Alternatively, you can construct a Connector and set any params,
then call addConnector(Connector) |
public StandardEngine getEngine() {
if(engine == null ) {
getServer();
engine = new StandardEngine();
engine.setName( "default" );
engine.setDefaultHost(hostname);
service.setContainer(engine);
}
return engine;
}
Access to the engine, for further customization. |
public StandardHost getHost() {
if (host == null) {
host = new StandardHost();
host.setName(hostname);
getEngine().addChild( host );
}
return host;
}
|
public StandardServer getServer() {
if (server != null) {
return server;
}
initBaseDir();
System.setProperty("catalina.useNaming", "false");
server = new StandardServer();
server.setPort( -1 );
service = new StandardService();
service.setName("Tomcat");
server.addService( service );
return server;
}
Get the server object. You can add listeners and
few more customizations. |
public StandardService getService() {
getServer();
return service;
}
Get the service object. Can be used to add more
connectors and few other global settings. |
protected void initBaseDir() {
if (basedir == null) {
basedir = System.getProperty("catalina.base");
}
if (basedir == null) {
basedir = System.getProperty("catalina.home");
}
if (basedir == null) {
// Create a temp dir.
basedir = System.getProperty("user.dir") +
"/tomcat." + port;
File home = new File(basedir);
home.mkdir();
if (!home.isAbsolute()) {
try {
basedir = home.getCanonicalPath();
} catch (IOException e) {
basedir = home.getAbsolutePath();
}
}
}
System.setProperty("catalina.home", basedir);
System.setProperty("catalina.base", basedir);
}
|
protected void initSimpleAuth() {
defaultRealm = new RealmBase() {
@Override
protected String getName() {
return "Simple";
}
@Override
protected String getPassword(String username) {
return userPass.get(username);
}
@Override
protected Principal getPrincipal(String username) {
Principal p = userPrincipals.get(username);
if (p == null) {
String pass = userPass.get(username);
if (pass != null) {
p = new GenericPrincipal(this, username, pass,
userRoles.get(username));
userPrincipals.put(username, p);
}
}
return p;
}
};
}
Initialize an in-memory realm. You can replace it
for contexts with a real one. |
protected void initWebappDefaults(StandardContext ctx) {
// Default servlet
StandardWrapper servlet =
addServlet(ctx, "default",
//new DefaultServlet());
// Or:
"org.apache.catalina.servlets.DefaultServlet");
servlet.addInitParameter("listings", "false");
servlet.setLoadOnStartup(1);
// class name - to avoid loading all deps
servlet = addServlet(ctx, "jsp",
"org.apache.jasper.servlet.JspServlet");
servlet.addInitParameter("fork", "false");
servlet.addInitParameter("xpoweredBy", "false");
// in default web.xml - but not here, only needed if you have
// jsps.
//servlet.setLoadOnStartup(3);
ctx.addServletMapping("/", "default");
ctx.addServletMapping("*.jsp", "jsp");
ctx.addServletMapping("*.jspx", "jsp");
// Sessions
ctx.setManager( new StandardManager());
ctx.setSessionTimeout(30);
// TODO: read mime from /etc/mime.types on linux, or some
// resource
for (int i = 0; i < DEFAULT_MIME_MAPPINGS.length; ) {
ctx.addMimeMapping(DEFAULT_MIME_MAPPINGS[i++],
DEFAULT_MIME_MAPPINGS[i++]);
}
ctx.addWelcomeFile("index.html");
ctx.addWelcomeFile("index.htm");
ctx.addWelcomeFile("index.jsp");
ctx.setLoginConfig( new LoginConfig("NONE", null, null, null));
// TODO: set a default realm, add simple API to add users
}
Init default servlets for the context. This should be the programmatic
equivalent of the default web.xml.
TODO: in normal tomcat, if default-web.xml is not found, use this
method |
public void setBaseDir(String basedir) {
this.basedir = basedir;
}
Tomcat needs a directory for temp files. This should be the
first method called.
By default, if this method is not called, we use:
- system properties - catalina.base, catalina.home
- $HOME/tomcat.$PORT
( /tmp doesn't seem a good choice for security ).
TODO: better default ? Maybe current dir ?
TODO: disable work dir if not needed ( no jsp, etc ). |
public void setConnector(Connector connector) {
this.connector = connector;
}
|
public void setDefaultRealm(Realm realm) {
defaultRealm = realm;
}
Set a custom realm for auth. If not called, a simple
default will be used, using an internal map.
Must be called before adding a context. |
public void setHost(StandardHost host) {
this.host = host;
}
Sets the current host - all future webapps will
be added to this host. When tomcat starts, the
host will be the default host. |
public void setHostname(String s) {
hostname = s;
}
The the hostname of the default host, default is
'localhost'. |
public void setPort(int port) {
this.port = port;
}
Set the port for the default connector. Must
be called before start(). |
public void setSilent() {
for (String s : silences) {
Logger.getLogger(s).setLevel(Level.WARNING);
}
}
|
public void start() throws Exception {
setSilent();
getServer();
getConnector();
server.initialize();
server.start();
}
Initialize and start the server. |
public void stop() throws Exception {
getServer().stop();
}
|