Tomcat is used as an application server, especially a web server. We generally deploy applications by packaging our own project projects into the directory specified by the server, and then starting the server to drive the application to start. Can we directly run our own project to start tomcat like spring boot? Let's talk about how I embed it into my own application?
[b]
The first step is to import the jar in the lib under the tomcat framework into your own application. The
second step to write your own web program code as follows . This is the parent class used for some class parameters of tomcat initialization before startup.
package org.apache.catalina.startup; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TestName; public abstract class LoggingBaseTest { protected Log log; private File tempDir; private List<File> deleteOnTearDown=new ArrayList<File>(); //Provide the name of the currently executing method @Rule public final TestName testName=new TestName(); public File getBuildDirectory(){ try { return new File(System.getProperty("tomcat.test.tomcatbuild"),".").getCanonicalFile(); } catch (IOException e) { return null; } } public File getTemporaryDirectory(){return tempDir;}; public void addDeleteOnTearDown(File file){ deleteOnTearDown.add(file); } @Before public void setUp() throws Exception{ tempDir =new File( System.getProperty("tomcat.test.temp","tmp")); if(!tempDir.mkdir()&&!tempDir.isDirectory()){ fail("Unable to create temporary directory for test"); } //Set catalina.base System.setProperty("catalina.base",tempDir.getAbsolutePath()); // Configure logging System.setProperty("java.util.logging.manager", "org.apache.juli.ClassLoaderLogManager"); System.setProperty("java.util.logging.config.file", new File( getBuildDirectory(), "conf/logging.properties").toString()); // Get log instance after logging has been configured log = LogFactory.getLog(getClass()); log.info("Starting test case [" + testName.getMethodName() + "]"); } @After public void tearDown() throws Exception { for (File file : deleteOnTearDown) { ExpandWar.delete(file); } deleteOnTearDown.clear(); } }
This is the tomcat configured before starting tomcat
package org.apache.catalina.startup; import static org.junit.Assert.fail; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URL; import java.util.List; import java.util.Map; import org.apache.catalina.Container; import org.apache.catalina.LifecycleException; import org.apache.catalina.Manager; import org.apache.catalina.Server; import org.apache.catalina.Service; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.AprLifecycleListener; import org.apache.catalina.core.StandardServer; import org.apache.catalina.session.ManagerBase; import org.apache.catalina.session.StandardManager; import org.apache.catalina.valves.AccessLogValve; import org.apache.tomcat.util.buf.ByteChunk; import org.junit.Before; public abstract class TomcatBaseTest extends LoggingBaseTest{ private Tomcat tomcat; private boolean accessLogEnabled=false; public static final String TEMP_DIR = System.getProperty("java.io.tmpdir"); public Tomcat getTomcatIntance(){ return tomcat; } public int getPort(){return tomcat.getConnector().getLocalPort();} public boolean isAccessLogEnabled(){return accessLogEnabled;} @Before @Override public void setUp() throws Exception { super.setUp(); CatalinaProperties.getProperty("foo"); File appBase=new File(getTemporaryDirectory(),"webapps"); if(!appBase.exists()&&!appBase.mkdir()){ fail("Unable to create appBase for test"); } //to Tomcat tomcat=new TomcatWithFastSessionIDs(); Connector connector=new Connector(); String protocol=getProtocol(); connector.setProtocol(protocol); connector.setAttribute("address", InetAddress.getByName("localhost").getHostAddress()); connector.setAttribute("connectionTimeout", 60000); connector.setPort(0); tomcat.setConnector(connector); tomcat.getService().addConnector(connector); if(protocol.contains("Apr")){ StandardServer server=(StandardServer) tomcat.getServer(); AprLifecycleListener listener =new AprLifecycleListener(); listener.setSSLRandomSeed("/dev/urandom"); connector.setAttribute("pollerThreadCount", Integer.valueOf(1)); } File catalinaBase=getTemporaryDirectory(); tomcat.setBaseDir(catalinaBase.getAbsolutePath()); tomcat.getHost().setAppBase(appBase.getAbsolutePath()); accessLogEnabled=Boolean.parseBoolean(System.getProperty("tomcat.test.accesslog","false")); if(accessLogEnabled){ String accessLogDirectory=System.getProperty("tomcat.test.reports"); if(accessLogDirectory==null) { accessLogDirectory =new File(getBuildDirectory(),"logs").toString(); } AccessLogValve alv=new AccessLogValve(); alv.setDirectory(accessLogDirectory); alv.setPattern("%h %l %u %t \"%r\" %s %b %I %D"); tomcat.getHost().getPipeline().addValve(alv); addDeleteOnTearDown(new File(catalinaBase, "webapps")); addDeleteOnTearDown(new File(catalinaBase, "work")); } } public String getProtocol(){ String protocol = System.getProperty("tomcat.test.protocol"); if(protocol==null){ protocol="org.apache.coyote.http11.Http11Protocol"; } return protocol; } public ByteChunk getUrl(String url,int readTimeout,String method) throws IOException{ ByteChunk out =new ByteChunk(); methodUrl(url, out, readTimeout, null, null, method); return out; } public ByteChunk getUrl(String url) throws IOException{ return getUrl(url,3000,"GET"); } public static int methodUrl(String path, ByteChunk out, int readTimeout, Map<String, List<String>> reqHead, Map<String, List<String>> resHead, String method) throws IOException{ URL url=new URL(path); HttpURLConnection connection=(HttpURLConnection) url.openConnection(); connection.setUseCaches(false); connection.setReadTimeout(readTimeout); connection.setRequestMethod(method); if(reqHead!=null){ for(Map.Entry<String,List<String>> entry:reqHead.entrySet()){ StringBuilder valueList=new StringBuilder(); for(String value:entry.getValue()){ if(valueList.length()>0){ valueList.append(","); } valueList.append(value); } connection.setRequestProperty(entry.getKey(), valueList.toString()); } } connection.connect(); int rc=connection.getResponseCode(); if(resHead!=null){ Map<String,List<String>> head =connection.getHeaderFields(); resHead.putAll(head); } InputStream is; if(rc<400){ is=connection.getInputStream(); }else { is=connection.getErrorStream(); } if(is!=null){ BufferedInputStream bis=null; try{ bis =new BufferedInputStream(is); byte[] buf =new byte[2048]; int rd =0; while((rd =bis.read(buf))>0){ out.append(buf,0,rd); } }finally{ if(bis!=null){ bis.close(); } } } return rc; } private class TomcatWithFastSessionIDs extends Tomcat{ @Override public void start() throws LifecycleException { Server server= getServer(); for(Service service:server.findServices()){ Container e=service.getContainer(); for(Container h:e.findChildren()){ for(Container c:h.findChildren()){ Manager m =c.getManager(); if(m==null){ m=new StandardManager(); c.setManager(m); } if(m instanceof ManagerBase){ ((ManagerBase)m).setSecureRandomClass("org.apache.catalina.startup.FastNonSecureRandom"); } } } } super.start(); } } }
This is actually setting up some war packages dynamically setting up servlets, dynamically setting up listeners, etc. running tomcat
package org.apache.catalina.startup; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.tomcat.util.buf.ByteChunk; import org.junit.Test; /** * test tomcat * @author lxy * */ public class TestTomcat extends TomcatBaseTest{ private class MyServletSesssion extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session= request.getSession(true); response.getWriter().print("sessionId:"+session.getId()); } } @Test public void testSingleWar() throws IOException{ Tomcat tomcat=getTomcatIntance(); File appDir=new File(getBuildDirectory(),"webapps/testTomcat.war"); try { tomcat.addWebapp("/", appDir.getAbsolutePath()); tomcat.start(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace (); } ByteChunk out = new ByteChunk(); methodUrl("http://localhost:"+getPort()+"/servlet1.do", out,10000, null, null, "GET"); System.out.println(out.toString()); } @Test public void testMethodUrl() throws IOException{ ByteChunk out = new ByteChunk(); methodUrl("http://www.baidu.com", out,10000, null, null, "GET"); System.out.println(out.toString()); } @Test public void testSession() throws Exception{ Tomcat tomcat =getTomcatIntance(); Context context =tomcat.addContext("", System.getProperty("java.io.tmpdir")); tomcat.addServlet(context, "myServlet", new MyServletSesssion()); context.addServletMapping("/myServlet.do","myServlet"); tomcat.start(); ByteChunk out=new ByteChunk(); methodUrl("http://localhost:"+getPort()+"/myServlet.do", out,3000, null,null, "GET"); System.out.println(out.toString()); } }
[/b]