# 一、启动关闭tomcat
需要先配置CATALINA_HOME
双击%CATALINA_HOME%\bin\startup.bat
双击%CATALINA_HOME%\bin\shutdown.bat
访问服务器:http://localhost:8080/index.jsp
因为服务器在本机上,所以主机名为localhost,表示本机
tomcat的默认端口为8080
index.jsp是主页
# 二、修改端口号
修改端口号,%CATALINA_HOME%\conf\server.xml,修改,把8080修改了即可。
http协议默认端口为80,也就是说http://localhost,等同与http://localhost:80
如果把Tomcat端口号修改成80,那么访问服务器就可以无需再给出端口号。
# 三.tomcat目录结构
![](http://h.yiniuedu.com/42813e3ba1fff6abb3c6bd945736427e)
1.bin:二进制可执行文件,例如startup.bat和shutdown.bat
>[danger]/bin目录
存放windows或者是Linux启动和关闭tomcat的脚本文件
/bin/catalina.sh
用于启动和关闭tomcat服务器
/bin/configtest.sh
用于检查配置文件
/bin/startup.sh
启动Tomcat脚本
/bin/shutdown.sh
关闭Tomcat脚本
2.conf:配置文件,例如:server.xml、context.xml、web.xml、tomcat-users.xml
>[danger]/conf目录
存放tomcat服务器的各种全局配置文件其中包括server.xml(Tomcat的主要配置文件)、tomcat-users.xml和web.xml等配置文件
/conf/server.xml
Tomcat 的全局配置文件
/conf/web.xml
为不同的Tomcat配置的web应用设置缺省值的文件
/conf/tomcat-users.xml
Tomcat用户认证的配置文件
3.lib:tomcat所需jar包
>[danger]/lib目录
存放Tomcat服务器运行所需的各种JAR文件(不能被web应用访问)
4.logs:日志文件
>[danger]/logs目录
存放Tomcat执行时的Log日志文件
/logs/localhost_access_log.*.txt
访问日志
/logs/localhost.*.log
错误和其它日志
/logs/manager.*.log
管理日志
/logs/catalina.*.log
Tomcat启动或关闭日志文件
5.temp:存放tomcat运行时产生的临时文件,当tomcat关闭后,这个目录中的文件可以删除
>[danger]/temp目录
存放Tomcat运行时所产临时文件
6.webapps:这个目录下的每个文件夹对应一个JavaWeb应用程序
>[danger]/webapps目录
Tomcat的主要Web发布目录,默认情况下把Web应用文件放于此目录(存放我们自己的JSP,Servlet类)
7.work:webapps下的应用程序在运行时会自动生成文件,就在work目录下。work目录删除了也没问题,但再次运行应用程序还要再生成work目录和文件。
>[danger]/work目录
Tomcat的工作目录,将JSP生成的Servlet源文件和字节码文件放到这个目录下
work目录下的文件
由Tomcat自动生成,这是Tomcat放置它运行期间的中间(intermediate)文件(诸如编译的JSP文件)地方。 如果当Tomcat运行时,你删除了这个目录那么将不能够执行包含JSP的页面。
# 四.创建JavaWeb目录:hello
1. 在webapps目录下创建一个hello目录,hello目录就是项目目录了;
2. 在hello目录下创建WEB-INF
3. 在WEB-INF下创建web.xml
4. 在WEB-INF下创建classes目录
5. 在WEB-INF下创建lib目录
6. 在hello目录下创建index.html
在web.xml文件中添加如下内容:
```
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
</web-app>
```
在index.html中添加如下内容:
```
<html>
<head>
<!--如果是html页面,charset设置为gb2312,可以防止出现乱码-->
<meta charset="gb2312"/>
<title>index.html</title></head>
<body>
<h1>hello主页</h1>
</body>
</html>
```
启动tomcat,打开客户端访问http://localhost:8080/hello/index.html
配置外部应用
外部应用既是把应用程序不放到Tomcat的wabapps目录下!而已放在外面,例如:d:/hello
在conf/server.xml下配置,指定外部应用的路径。
```
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="yiniuedu_hello" docBase="d:/hello"/>
</Host>
```
在元素下添加元素,path为URL访问路径,docBase为外部应用的目录。
在浏览器地址栏中访问:http://localhost:8080/yiniuedu_hello/index.html
在conf/catalna/localhost下添加配置文件,指定外部应用路径
在conf/catalna/localhost目录下创建yiniuedu_hello.xml文件,其中yiniuedu_hello就是URL访问路径
在yiniuedu_hello.xml文件中添加:,docBase指定外部应用的目录。
缺省web应用
在webapps目录下有一个ROOT目录,它是缺省web应用,访问这个应用的路径:http://localhost:8080/index.jsp
如果把web应用的内部放到webapps/ROOT下,访问URL路径中不用给出应用名称。
配置虚拟主机
希望:http://cms.yiniuedu.com访问web应用。
这需要把域名http://cms.yiniuedu.com映射成IP地址:127.0.0.1
需要把tomcat端口号修改为80
需要在server.xml中配置主机,并指定主机的应用目录
在应用目录中添加名为ROOT的web应用。
1). 找到C:\WINDOWS\system32\drivers\etc\hosts文件,添加127.0.0.1 http://cms.yiniuedu.com
2). 在conf/server.xml中修改端口为80
3). 在conf/server.xml中添加元素
```
<Host name="cms.yiniuedu.com" appBase="d:/myapps" unpackWARs="true" autoDeploy="true">
</Host>
```
* name:指定该主机域名为cms.yiniuedu.com
* appBase:指定该主机的应用目录为d:/myapps
4). 在d:/myapps下创建名为ROOT的web应用。
# 五、tomcat服务器顶层结构
免费、开源、跨平台的Tomcat无疑是我们开始学习Java EE的第一个服务器,会用对于日常开发完全够用了,但是还是要学一下Tomcat相关的原理和设计思想等,对于以后相关的扩展和优化有着重要的作用。下边是学习Tomcat,翻看Tomcat源码的一些总结和感悟,作为笔记查看。
## 1、Tomcat服务器顶层结构
俗话说,站在巨人的肩膀上看世界,一般学习的时候也是先总览一下整体,然后逐个部分个个击破,最后形成思路,了解具体细节。Tomcat 的结构很复杂,但是 Tomcat 也非常的模块化,找到了 Tomcat 最核心的模块,问题才可以游刃而解。先上一张Tomcat的顶层结构图,如下:
![](http://h.yiniuedu.com/4937477b6b0bacdcb78e2aad497f57f9)
Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务。
Service主要包含两个部分:Connector和Container。从上图中可以看出 Tomcat 的心脏就是这两个组件,他们的作用如下:
Connector用于处理链接相关的事情,并提供Socket与Request和Response相关的转化;
Container用于封装和管理Servlet,以及具体处理Request请求;
一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但是可以有多个Connectors,这是因为一个服务可以有多个连接,如同时提供http和https链接,也可以提供向相同协议不同端口的连接。
多个 Connector 和一个 Container 就形成了一个 Service,有了 Service 就可以对外提供服务了,但是 Service 还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非 Server 莫属了。所以整个 Tomcat 的生命周期由 Server 控制。
另外,上述的包含关系或者说是父子关系,都可以在tomcat的conf目录下的server.xml配置文件中看出,下图是删除了注释内容之后的一个完整的server.xml配置文件(Tomcat版本为8.0)
![](http://h.yiniuedu.com/1658e4f55f8d8d932c9436d6025f0d83)
详细的配置文件文件内容可以到Tomcat官网查看:[http://tomcat.apache.org/tomcat-8.0-doc/index.html](http://tomcat.apache.org/tomcat-8.0-doc/index.html)
上边的配置文件,还可以通过下边的一张结构图更清楚的理解:
![](http://h.yiniuedu.com/2fa9acc36b516832eaf2fb5b6969d528)
Server标签设置的端口号为8005,shutdown=”SHUTDOWN” ,表示在8005端口监听“SHUTDOWN”命令,如果接收到了就会关闭Tomcat。一个Server有一个Service,当然还可以进行配置,一个Service有多个,Service左边的内容都属于Container的,Service下边是Connector。
总结:
Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container。
## 2、Tomcat的启动过程
首先看一张Tomcat启动的时序图,如下:
![](http://h.yiniuedu.com/87d46e678458439bb25720785994aeea)
Tomcat的启动入口main方法是在Bootstrap类里,但具体的执行过程是在Catalina里边,这样做可以使得把启动的入口和具体的管理类进行分开,从而可以方便的创建多种启动的方式。
Catalina是整个Tomcat的管理类,他有三个方法load、start、stop分别用来管理整个服务器的生命周期。load方法用于加载tomcat/conf目录下的server.xml配置文件,用来创建Server并调用Server的init方法进行初始化操作,start用于启动服务器器,stop用于停止服务器,start和stop方法在内部分别调用Server的start和stop方法,load方法在内部调用了 Server的init方法,这三个方法都会按层次分逐层调用相应的方法。
从上述的时序图,按着从上到下,从左到右的顺序,完全可以了解整个Tomcat的启动顺序。
上图中看到了几个陌生的名字,下边具体说明。
### 2.1、Bootstrap的启动过程
Bootstrap作为Tomcat的启动入口,其main方法如下:
```
public static void main(String args[]) {
//首先判断Bootstrap daemon 是否为空,就是创建一个Bootstrap实例daemon
if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init(); //初始化ClassLoader,并用ClassLoader创建了一个Catalina实例,并将这个实例赋值给了cataLinaDaemon
} catch (Throwable t) {
handleThrowable(t);
t.printStackTrace();
return;
}
daemon = bootstrap;
} else {
// When running as a service the call to stop will be on a new
// thread so make sure the correct class loader is used to prevent
// a range of class not found exceptions.
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
}
try {
String command = "start"; //指定默认的执行指令是start
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args); //BootStrap的load方法,其实是调用Calatina的load方法
daemon.start();
} else if (command.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true); //setWait方法 主要是为了设置Server启动完成后是否进入等待状态的标志,如果为true则进入,否则不进入
daemon.load(args); //load方法用于加载配置文件,创建并初始化Server
daemon.start(); //start方法用于启动服务器
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else if (command.equals("configtest")) {
daemon.load(args);
if (null == daemon.getServer()) {
System.exit(1);
}
System.exit(0);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
// Unwrap the Exception for clearer error reporting
if (t instanceof InvocationTargetException &&
t.getCause() != null) {
t = t.getCause();
}
handleThrowable(t);
t.printStackTrace();
System.exit(1);
}
}
```
(1)上述执行的bootstrap.init()方法源代码如下:
![](http://h.yiniuedu.com/18c295a4602c6234f7a8e818cda9f579)
(2)main方法里边,首先创建一个Bootstrap,并执行init方法进行初始化,然后出来main方法里传入的参数,如果参数为空,默认为start。
(3)在init方法里初始化ClassLoader,并用ClassLoader创建了Catalina实例,然后赋值给catalinaDaemon变量,后边对命令的操作都要使用catalinaDaemon来具体的执行;
(4)在start命令的处理调用的时候有三个方法:setAwait、load
、start。这三个方法在内部调用了Clatalina的相应的方法进行具体的执行,只不过是用反射来调用的。
### 2.2、Catalina的启动过程
Catalina的启动主要调用setAwait、load和start方法来实现,setAwait方法用于设置Server启动完成后是否进入等待状态的标志,如果为true则进入,否则不进入;load方法用于加载配置文件,创建并初始化Server;start用于启动服务器。
Catalina的load方法根据con/server.xml文件进行创建对象的,并赋值给server属性。
### 2.3、Server的启动过程
Server是一个接口,继承自Lifecycle ,接口定义如下:
```
public interface Server extends Lifecycle {
}
```
![](http://h.yiniuedu.com/ca3f923f9e748aac48d56205f00c93c3)
看接口的结构图可以看出,其中包含了addService、findService、removeService三个主要的方法,用来增加、查找、删除Service。Server的init方法和start方法分别循环调用了每个Service方init方法和start方法来启动所有的Service。
Server 的默认实现是:org.apache.catalina.core.StandardServer,继承关系图如下:
![](http://h.yiniuedu.com/e26bd4835736986bb70bb56f79534c20)
StandardServer的initInternal和startInternal方法分别循环调用了每一个Service的start和init方法。
![](http://h.yiniuedu.com/22aa146975e882f530953868db664baf)
### 2.4、Service的启动过程
Service是一个接口,继承自Lifecycle ,接口定义如下:
~~~
public interface Service extends Lifecycle {
}
~~~
Service 接口定义的方法和属性如下:
![](http://h.yiniuedu.com/da2187fb3714f59686c0c4388f5a354e)
Service的默认实现是:org.apache.catalina.core.StandardService。StandardService和StandardServer有相似的继承关系,如下图:
![](http://h.yiniuedu.com/f1c01efcda4b95dbd7e9205088277e90)
StandardService的initInternal方法如下:
```
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
if (engine != null) {
engine.init();
}
// Initialize any Executors
for (Executor executor : findExecutors()) {
if (executor instanceof JmxEnabled) {
((JmxEnabled) executor).setDomain(getDomain());
}
executor.init();
}
// Initialize mapper listener
mapperListener.init();
// Initialize our defined Connectors
synchronized (connectorsLock) {
for (Connector connector : connectors) {
connector.init();
}
}
}
```
StandardService的startInternal方法如下
```
@Override
protected void startInternal() throws LifecycleException {
if(log.isInfoEnabled())
log.info(sm.getString("standardService.start.name", this.name));
setState(LifecycleState.STARTING);
// Start our defined Container first
if (engine != null) {
synchronized (engine) {
engine.start();
}
}
synchronized (executors) {
for (Executor executor: executors) {
executor.start();
}
}
mapperListener.start();
// Start our defined Connectors second
synchronized (connectorsLock) {
for (Connector connector: connectors) {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();
}
}
}
}
```
可以看出,StandardService的initInternal和startInternal方法主要调用container、executors、mapperListener、connectors的init和start方法。
mapperListener是Mapper的监听器,用来监听Container容器的变化;executors是用在connectors中管理线程的线程池,在server.xml文件中可以看到,默认是注释的:
![](http://h.yiniuedu.com/350e8b5cf889ca26c28c333345cc262c)
## 3、总结
上述的几小节,大致记录了一下Tomcat的整体结构,在上边介绍的时候,也有一些没有写到的东西,比如说Tomcat生命周期管理的接口Lifecycle、Connector、Container以及Tomcat如何进行通信,如何解析和处理具体的Http请求,这些会在以后的学习中不断记录下来。
- Java Web项目开发学习手册
- 一、B/S开发环境搭建
- 1.1 tomcat服务器目录结构及作用
- 1.2 在IDE开发工具上配置tomcat服务器
- 1.3 简单web项目在tomcat服务器上运行的方法
- 1.4 开发工具设置
- 1.5 总结
- 二、Servlet技术应用
- 2.1 HttpServlet中的主要方法及应用
- 2.1.1 基于Eclipse完成一个JavaWeb项目
- 2.2 HttpRequest,HttpResponse的应用
- 2.2.1客户端请求
- 2.2.2服务器响应
- 2.2.3Servlet HTTP 状态码
- 2.2.4图片验证码类
- 2.2.5注册模拟实现(带验证码)
- 2.3 ServletConfig对象和ServletContext对象的概念
- 2.4 总结
- 三、JSP技术应用
- 3.1 JSP基本语法
- 3.2 JSP标签和指令
- 3.3 JSP中的隐式对象
- 3.4 常用应用操作
- 3.4.1 JSP客户端请求
- 3.4.2 JSP服务器响应
- 3.4.3 HTTP状态码
- 3.4.4 表单处理
- 3.4.5 过滤器
- 3.4.6 Cookie处理
- 3.4.7 Session处理
- 3.4.8 文件上传
- 3.4.9 日期处理
- 3.4.10 页面重定向
- 3.4.11 点击量统计
- 3.4.12 自动刷新
- 3.4.13 发送邮件
- 3.5 JSP高级应用
- 3.5.1 JSP标准标签库(JSTL)
- 3.5.2 JSP连接数据库
- 3.5.3 JSP XML数据处理
- 3.5.4 JSP JavaBean
- 3.5.5 自定义标签
- 3.5.6 表达式语言
- 3.5.7 异常处理
- 3.5.8 调试
- 3.5.9 JSP国际化
- 3.6 实践代码
- 3.6.1 实践代码
- 3.6.2 项目实战
- 3.7 总结
- 四、MVC思想的理解和搭建MVC
- 4.1 MVC设计模式的思想
- 4.2 MVC设计模式的实现步骤
- 4.3 项目实践
- 4.4 总结
- 五、EL表达式和JSTL技术
- 5.1 EL表达式及其应用
- 5.2 常用的JSTL标签的应用
- 5.3 项目实践
- 5.4 总结
- 六、Cookie和Session
- 6.1 cookie对象的概念和应用
- 6.2 session对象的概念和应用
- 6.3 项目实践
- 6.4 总结
- 七、过滤器技术应用
- 7.1 Filter的概念及应用
- 7.2 Filter、FilterChain、FilterConfig 介绍
- 7.3 用户登录过滤案例
- 7.4 项目实战
- 7.5总结
- 八、异步请求技术
- 8.1 JSON数据格式
- 8.2 使用AJAX实现异步请求
- 8.3 用户名校验案例
- 8.4小结
- 综合项目技术实训
- 1.BS项目开发项目实战
- 2.项目需求分析和系统设计
- 2.1需求分析
- 2.2类型模型设计
- 2.3原型设计
- 3.项目数据库分析和系统设计
- 4.BS项目编程实现
- 4.1搭建框架和命名规约
- 4.2实现步骤
- 4.2.1创建实体类
- 4.2.2创建过滤器类
- 4.2.3创建工具类
- 4.2.4创建DAO接口及其实现类
- 4.2.5创建Service接口及其实现类
- 4.2.6创建测试类
- 4.2.7创建控制器类
- 5.企业开发流程规范
- 6.总结
- 九、练习题及答案
- 企业开发常用技术
- 1.Maven技术
- Java命名规范解读
- 参考资料
- 开发中常用的应用服务器和Web服务器