1、Tomcat是什么
Tomcat是一个开源程序,使用Java语言编写,主要用于支持Java Web应用程序。
1)作为Web服务器:
Web服务器是安装在服务器端的一款软件,把写的Web项目部署到Tomcat服务器软件中,当Web服务器软件启动后,部署在Web服务器软件中的页面就可以直接通过浏览器来访问了。Web服务器对HTTP协议的操作进行了封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。
Tomcat可以作为Web服务器使用,处理静态HTML页面。当客户端请求HTML页面时,Tomcat会接收请求并将对应的HTML页面返回给客户端。这意味着Tomcat具备了基本的Web服务器功能,可以提供静态内容的访问。Tomcat的静态内容处理能力较弱,它主要专注于处理动态Web内容。
2)作为Web应用服务器:
Web应用服务器是一种特殊类型的Web服务器,用于提供运行Web应用程序的环境。Web应用服务器接收来自Web浏览器的HTTP请求,并处理与应用程序相关的特定请求,如处理业务逻辑或与数据库的交互。
Tomcat的核心功能是作为Web应用服务器,支持Java Servlet和JSP技术。通过与Servlet容器集成,Tomcat能够处理来自客户端的请求,并将请求传递给相应的Servlet进行处理。Servlet是一种Java类,可以接收请求、处理逻辑并生成动态内容。在处理完请求后,Servlet将生成的动态内容返回给Tomcat,并由Tomcat返回给客户端。
除了支持Servlet,Tomcat还支持JSP(JavaServer Pages)。JSP允许开发人员在HTML页面中嵌入Java代码,使得Web页面能够动态生成内容。当客户端请求JSP页面时,Tomcat会先将其编译成Servlet,然后执行该Servlet生成动态内容。因此,Tomcat作为Web应用服务器时,主要关注于处理动态Web内容的请求和生成动态Web内容的能力。
2、Tomcat的作用
关注Java应用的解析和执行,为Java Web应用程序提供运行环境。
处理Java语言编写的动态网页,特别是Servlet和JSP页面。
1)处理HTML页面(HTTP协议解析)
- 接收HTTP请求:
Tomcat通过监听特定的端口(默认为8080),等待客户端的请求。一旦收到请求,Tomcat会根据请求的URL和协议类型,将其传递给相应的处理程序。
- 解析请求:
Tomcat接收到请求后,会将其解析为Java对象,以便后续的处理。解析过程中,Tomcat会提取请求中的信息,如请求方法、请求参数等。
- 处理请求:
在接收到请求后,Tomcat会根据请求的类型和内容调用相应的Java类和方法进行处理。如果请求涉及到数据库操作,Tomcat会与数据库进行交互,执行相应的SQL语句。
- 生成响应:
处理完请求后,Tomcat会生成响应对象,并将响应内容填充到响应对象中。响应内容可以是HTML页面、JSON数据或其他格式的数据。
- 发送响应:
最后,Tomcat会将响应发送回客户端。在发送响应时,Tomcat会根据客户端的协议和需求,将响应转换为相应的格式(如HTML、JSON等),并通过HTTP协议发送给客户端。
2)运行Java Web应用程序(Servlet容器与JSP容器)
Servlet用于创建动态Web内容。它是一个可重用的组件,可以处理来自Web客户端的请求,并将响应发送回客户端。Servlet可以与JSP页面结合使用,以生成动态Web内容。JSP页面允许开发人员将Java代码嵌入到HTML页面中,以便在请求时生成动态内容。JSP页面可以被视为一种特殊的Servlet,用于生成HTML页面。
3、自定义Tomcat实现
用于理解Tomcat原理和流程、有助于理解Servlet。
1)MyRequest:处理请求
public class MyRequest{
//请求方法 get/post
private String requestMethod;
//请求地址
private String requestUrl;
//创建方法 作用:解析 按照请求格式
public MyRequest(InputStream inputStream) throws Exception{
//定义一个缓冲区域
byte[] buffer =new byte[1024];
//定义一个读取数据的长度
int len=0;
//定义请求的变量
String str=null;
//读取数据
if ((len=inputStream.read(buffer))>0){
str=new String(buffer,0,len);
}
//对字符串进行分割得到一个字符串的数组 \n换行
//请求头 请求行 空格 请求体
String s = str.split("\n")[0]; //取数组里的第一个 请求头这一行
//得到的格式:GET/ HTTP/1.1
//再进行切割 按空格切割
String[] params = s.split(" ");
this.requestMethod=params[0]; //GET
this.requestUrl=params[1]; //地址
}
//赋值 get set方法
public String getRequestMethod() {
return requestMethod;
}
public void setRequestMethod(String requestMethod) {
this.requestMethod = requestMethod;
}
public String getRequestUrl() {
return requestUrl;
}
public void setRequestUrl(String requestUrl) {
this.requestUrl = requestUrl;
}
2)MyResponse:处理响应
public class MyResponse {
//属性 输出流
private OutputStream outputStream;
//构造器
public MyResponse(OutputStream outputStream) {
this.outputStream = outputStream;
}
//方法 响应 拼接 按照响应格式
public void write(String str) throws Exception{
StringBuilder builder=new StringBuilder();
builder.append("HTTP/1.1 200 OK\n")
.append("Content-type:text/html\n")
.append("\r\n") //空行换行必须写\r\n
.append("<html>")
.append("body")
.append("<h1>"+ str + "</h1>")
.append("</body>")
.append("</html>");
this.outputStream.write(builder.toString().getBytes());
this.outputStream.flush();
this.outputStream.close();
}
}
3)MyMapping:映射关系
//映射关系
public class MyMapping {
public static HashMap<String,String> mapping=new HashMap<>();
//一个静态代码块 优先执行
static { //请求 与 处理逻辑的类 的映射关系
mapping.put("/mytomcat","com.ss.MyServlet"); //请求地址 自定义类的地址
}
//方法
public HashMap<String,String> getMapping(){
return mapping;
}
}
4)MyHttpServlet:父类
//这是父类
public abstract class MyHttpServlet {
//定义常量
public static final String METHOD_GET="GET";
public static final String METHOD_POST="POST";
public abstract void doGet(MyRequest request,MyResponse response)throws Exception;
public abstract void doPost(MyRequest request,MyResponse response)throws Exception;
//根据请求方法来判断调用那种处理方法
public void service(MyRequest request,MyResponse response)throws Exception{
if(METHOD_GET.equals(request.getRequestMethod())){
doGet(request,response);
}else if(METHOD_POST.equals(request.getRequestMethod())){
doPost(request,response);
}
}
}
5)MyServlet:子类
//这是子类
public class MyServlet extends MyHttpServlet{
//实现方法
@Override
public void doGet(MyRequest request, MyResponse response) throws Exception {
//子类throws Exception 在父类方法里也要抛出
response.write("mytomcat");
}
@Override
public void doPost(MyRequest request, MyResponse response) throws Exception{
response.write("post tomcat");
}
}
6)MyServer:服务端
//服务端
public class MyServer {
//定义服务端的接收程序 接收socket(套接字)请求
public static void startServer(int port)throws Exception{
//定义服务端套接字
ServerSocket serverSocket =new ServerSocket(port);
//定义客户端套接字 为空 每一个请求是一个套接字
Socket socket=null;
//请求可以发多条 用一个死循环接收
while (true){
socket=serverSocket.accept();
//获取输入流 输出流
InputStream inputStream=socket.getInputStream();
OutputStream outputStream=socket.getOutputStream();
//定义请求对象
MyRequest request=new MyRequest(inputStream);
//定义响应对象
MyResponse response=new MyResponse(outputStream);
String clazz =new MyMapping().getMapping().get(request.getRequestUrl());
if (clazz!=null){
Class<MyServlet>myservletClass= (Class<MyServlet>) Class.forName(clazz);//动态加载类(反射)
//创建对象
MyServlet myServlet = myservletClass.newInstance();
myServlet.service(request,response);
}
}
}
public static void main(String[] args) {
try {
startServer(10010);
} catch (Exception e) {
e.printStackTrace();
}
}
}
启动测试:
打开浏览器访问:localhost:10010/mytomcat (MyMapping里的映射地址)
访问结果(页面显示):mytomcat(这是MyServlet类里doGet方法里-write方法中写入的)
如果改动这两个位置里面的内容,重启后访问地址和访问结果也相应改动。
本案例未考虑多线程、并发的情况,仅用于帮助理解Tomcat及Servlet,实际开发中直接用Tomcat。
4、什么是Servlet
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
在Tomcat中,Servlet被视为一种独立的线程,每个Servlet都运行在自己的线程中。当客户端发送请求时,Tomcat会根据请求的URL和协议类型将其映射到相应的Servlet进行处理。一旦接收到请求,Servlet就会执行相应的业务逻辑,然后将结果通过Tomcat返回给客户端。
此外,Tomcat还提供了一些内建的Servlet,用于处理常见的Web应用程序任务,如会话管理、文件上传等。这些内建的Servlet简化了开发人员的工作,使得Java Web应用程序的开发更加高效和便捷。