Tomcat(1)作用及自定义Tomcat实现

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("")
                .append("body")
                .append("

"+ str + "

") .append("") .append(""); this.outputStream.write(builder.toString().getBytes()); this.outputStream.flush(); this.outputStream.close(); } }

3)MyMapping:映射关系

//映射关系
public class MyMapping {
    public static HashMap mapping=new HashMap<>();
    //一个静态代码块 优先执行
    static {  //请求 与 处理逻辑的类 的映射关系
        mapping.put("/mytomcat","com.ss.MyServlet");  //请求地址  自定义类的地址
    }
    //方法
    public HashMap 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){
                ClassmyservletClass= (Class) 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应用程序的开发更加高效和便捷。
 

你可能感兴趣的:(tomcat,servlet,http)