一、前言
我们在写javaweb程序的时候有没有考虑如果没有tomcat,我们怎么给客户端返回响应数据?既然能返回响应数据,为什么还要使用tomcat?
什么是tomcat,以及tomcat历史版本发展情况,每个版本servlet规范的支持,相关的许可。
最后再介绍如何下载tomcat、安装tomcat、启动tomcat、运行tomcat以及tomcat目录结构、idea中如何使用tomcat等相关的基础知识点。
二、为什么要使用tomcat?
介绍这个问题之前,我们先来复习一下javaweb编码中不可或缺的http协议。
http (HyperText Transfer Protocol) 超文本传输协议,规定了浏览器和服务之间传输数据的规则
下面演示一个简单得http协议代码,请求本地服务,返回给浏览器msg
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8080); // 监听指定端口
System.out.println("server is running...");
for (;;) {
Socket sock = ss.accept();
System.out.println("connected from " + sock.getRemoteSocketAddress());
Thread t = new Handler(sock);
t.start();
}
}
}
class Handler extends Thread {
Socket sock;
public Handler(Socket sock) {
this.sock = sock;
}
public void run() {
try (InputStream input = this.sock.getInputStream()) {
try (OutputStream output = this.sock.getOutputStream()) {
handle(input, output);
}
} catch (Exception e) {
try {
this.sock.close();
} catch (IOException ioe) {
}
System.out.println("client disconnected.");
}
}
private void handle(InputStream input, OutputStream output) throws IOException {
System.out.println("Process new http request...");
var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
// 读取HTTP请求:
boolean requestOk = false;
String first = reader.readLine();
if (first.startsWith("GET / HTTP/1.")) {
requestOk = true;
}
for (;;) {
String header = reader.readLine();
if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
break;
}
System.out.println(header);
}
System.out.println(requestOk ? "Response OK" : "Response Error");
if (!requestOk) {
// 发送错误响应:
writer.write("HTTP/1.0 404 Not Found\r\n");
writer.write("Content-Length: 0\r\n");
writer.write("\r\n");
writer.flush();
} else {
// 发送成功响应:
String data = "<html><body><h1>Hello, world!</h1></body></html>";
int length = data.getBytes(StandardCharsets.UTF_8).length;
writer.write("HTTP/1.0 200 OK\r\n");
writer.write("Connection: close\r\n");
writer.write("Content-Type: text/html\r\n");
writer.write("Content-Length: " + length + "\r\n");
writer.write("\r\n"); // 空行标识Header和Body的分隔
writer.write(data);
writer.flush();
}
}
}
这里的核心代码是,先读取HTTP请求,这里我们只处理GET /的请求。当读取到空行时,表示已读到连续两个\r\n,说明请求结束,可以发送响应。发送响应的时候,首先发送响应代码HTTP/1.0 200 OK表示一个成功的200响应,使用HTTP/1.0协议,然后,依次发送Header,发送完Header后,再发送一个空行标识Header结束,紧接着发送HTTP Body,在浏览器输入http://localhost:8080/就可以看到响应页面。
ok,上面我们可以 看到只是单单给浏览器返回一句话,代码量也有不少,别说一个大型的web系统。对于这种情况就有公司对http操作进行封装,使程序员不必对协议再进行操作,让web开发变得便捷,而tomcat就是对http操作的封装。
三、tomcat历史
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。
当前Tomcat存在5个主要版本,分别支持不同版本的规范,其对规范及JDK的版本支持如下
Tomcat最后两个版本并不是顺序发布的。2015年11月,Tomcat发布了重要的里程碑版本9.0(目前仍为alpha版本)。在该版本中,Tomcat依赖最新的JDK8,使用了JDK8最新的语法特性,支持最新的Servlet规范 (4.0),并增加了对HTTP/2的支持。2016年3月,考虑到9.0版本的变更范围以及发布进度,Tomcat在8.0的基础上又发布了一个中间版本–8.5.它的主体架构延续自8.0,同时又实现了部分9.0的主要特性,以便用来取代8.0版本。
四、tomcat许可
Tomcat以Apache License许可的方式进行发布,具体许可内容参见http://apache.org/licensesLICENSE-2.0。主要概括如下。
- Tomcat完全免费,可用于任何商业或者非商业产品,而不必支付任何费用
- 修改Tomcat并发布变更版本的用户不必公开修改部分的源代码。
- 修改Tomcat的用户不必将其变更捐献给Apache软件基金会
- 所有针对Tomcat源代码或二进制文件的重新发布均须包含Apache许可
- 任何重新发布所包含的资料必须经过Apache软件基金会批准
- 无Apache基金会的许可,派生自Tomcat源代码的产品不能命名为“Tomcat”、“Apache”、“Jakarta”
五、tomcat基本使用
1、下载、安装、启动、停止
官网下载地址:https://tomcat.apache.org/
选择下载的版本,推荐压缩包的方式直接下载解压即可
目录结构
启动和运行
双击Tomcat下的bin下的startup.bat启动Tomcat或者命令行在tomcat目录下执行如下命令
D:\apache-tomcat-8.5.82\bin>catalina run
在浏览器的地址栏中输入http://localhost:8080,看到如下页面证明启动成功
启动失败常见问题
点击 startup.bat启动Tomcat启动出现黑窗口一闪而过
主要原因:java环境配置问题,配置java home环境名必须是JAVA_HOME
停止tomcat
找到bin下的shutdown.bat
如果是窗口启动的,关闭窗口即可停止tomcat
2、端口配置
默认端口是8080,如果出现端口占用,可以通过以下方式修改
1)找到 Tomcat 目录下的 conf 文件夹
2)进入 conf 文件夹里面找到 server.xml 文件
3)打开 server.xml 文件
4)在 server.xml 文件里面找到下列信息
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"redirectPort="8443" />
port="8080"改成你想要的端口,修改完重启tomcat才能生效
3、tomcat部署项目
在Tomcat中部署Web应用的方式主要有如下几种:
1、利用Tomcat的自动部署。把web应用拷贝到webapps目录。Tomcat在启动时会加载目录下的应用,并将编译后的结果放入work目录下。
一般将项目打包成war放到webapps目录下,tomcat会自动解压缩war文件
浏览器输入localhost:8080/项目名即可访问
2、使用Manager App控制台部署。在tomcat主页点击“Manager App” 进入应用管理控制台,可以指定一个web应用的路径或war文件。
3、修改conf/server.xml文件,增加Context节点可以部署应用。
4、在conf/Catalina/localhost/ 路径下增加 abx.xml文件,内容如下,内容是Context节点,可以部署应用
<Context path="/demo" docBase="E:\demo"/>
当浏览器输入访问地址如:
http://ip:port/
没有工程名时候,默认访问的是ROOT工程
当浏览器输入访问地址如:
http://ip:port/工程名/
没有资源名,默认访问index.html页面
4、tomcat web项目结构
一个javaweb项目要能够在tomcat下部署运行,需要满足一定的目录结构格式,在tomcat目录下的webapps目录下创建一个mail项目,结构如下,然后启动tomcat,localhost:8080/mail即可访问
注意:WEB-INF目录是受保护的,外界不能直接访问,想让外界响应到,不要写在WEB-INF内。所以写的网页没有在WEB-INF中
以后创建的java web maven项目,开发完之后,需要package,package完项目的结构也是遵循上面项目结构的,对照如下
- 编译后的java字节码文件和resouce的资源文件,放到了WEB-INF下的class目录下
- pom.xml 中依赖坐标对应的jar包,放入WEB-INF下的lib目录下
六、idea中使用tomcat
1、idea中创建maven web项目
方式1、使用maven骨架方式
1、选择web项目骨架
接着填写项目名以及maven坐标,finish即可,我们可以删除pom里面不用的依赖,pom依赖如
2、补齐缺失的目录结构
main下分别创建java和resource目录即可
方式2、不使用maven骨架方式
1、不勾选骨架创建项目
2、pom添加war的打包方式
3、补齐web项目目录结构:webapp目录即可
2、idea集成本地tomcat
上面我们创建好项目之后,如果想要运行将项目部署到tomcat下并运行,之前的方式是首先package,然后将打包好的war包复制到本地tomcat下的webapps即可运行,这个过程还是比较繁琐。
在idea中可以直接继承本地tomcat进行运行项目
如下
添加local tomcat
部署项目
选择要部署得项目,然后apply,部署完之后点击运行即可
备注:如何是普通的web项目,不是maven项目,如何将第三方jar添加到项目中?
首先在当前项目WEB-INF下创建lib文件夹,将第三方jar复制到lib下
打开Project structure中
添加jar
apply
3、idea使用tomcat 插件
上面2介绍了如何把maven web项目部署到本地tomcat中,并运行起来,接下来介绍不使用本地tomcat,而是用tomcat maven 插件的方式运行maven 项目