JAVA Web 学习(二)ServLet

二、动态web 资源开发技术——Servlet

Servlet(小服务程序)是一个与协议无关的、跨平台的Web组件,由Servlet容器所管理。运行在服务器端,可以动态地扩展服务器的功能,并采用“请求一响应”模式提供Web服务。 Servlet的主要功能是交互式地浏览和修改数据,生成动态Web内容。 Servlet是按照Servlet规范编写的Java类。

Servlet生命周期
Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:
① 加载和实例化:默认情况下,当servlet第一次被访问时,由容器创建servlet对象。
② 初始化:在Servlet实例化之后,容器将调用servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次。
③ 请求处理:每次请求servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。
④ 服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收。
Servlet常用方法
初始化方法,在Servlet被创建时执行,只执行一次。void init(ServletConfig config)
提供服务方法,每次Servlet被访问,都会调用该方法。void service(ServletRequest req, ServletResponse res)
销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet。void destroy()
获取ServletConfig对象ServletConfig getServletConfig()
获取Servlet信息String getServletInfo()

三、动态的网页技术——JSP

JAVA Web 学习(二)ServLet_第1张图片

**概念:**Java Server Pages,Java服务端页面。
一种动态的网页技术,其中既可以定义HTML、JS、CSS等静态内容,还可以定义Java代码的动态内容。
JSP = HTML + Java,JSP本质上就是一个Servlet 。
**JSP的作用:**简化开发,避免了在Servlet中直接输出HTML标签。

原理:JSP本质上就是一个Servlet 。JSP在被访问时,由JSP容器(Tomcat)将其转换为Java文件(Servlet),在由JSP容器(Tomcat)将其编译,最终对外提供服务的其实就是这个 字节码文件 。

**缺点:**JSON 只支持 get,因为 script 标签只能使用 get 请求; JSONP 需要后端配合返回指定格式的数据。

实例

//test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title heretitle>
head>
<body>
<%
    Date date=new Date();
    out.write(date.toLocaleString());
%>
body>
html>

四、Web服务器——Tomcat

结构:

Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户.而Servlet是一种运行在支持Java语言的服务器上的组件. Servlet最常见的用途是扩展Java Web服务器功能。

JAVA Web 学习(二)ServLet_第2张图片

①Tomcat 通过 Socket 读取到这个请求(一个字符串), 并按照 HTTP 请求的格式来解析这个请求, 根据请求中的 Context Path 确定一个 webapp, 再通过 Servlet Path 确定一个具体的 类. 再根据当前请求的方法 (GET/POST/…), 决定调用这个类的 doGet 或者 doPost 等方法。

②表示Servlet容器把响应对象ServletResponse中的处理结果转发给Web服务器,通知Web服务器以HTTP响应的方式把结果发送到客户端,同时把控制返回Web服务器。

class Tomcat{
    // 用来存储所有的 Servlet 对象
    private List<Servlet> instanceList = new ArrayList<>();
    public void start() {
    // 根据约定,读取 WEB-INF/web.xml 配置文件;
    // 并解析被 @WebServlet 注解修饰的类
    // 假定这个数组里就包含了我们解析到的所有被 @WebServlet 注解修饰的类.
        Class<Servlet>[] allServletClasses = ...;
    // 这里要做的的是实例化出所有的 Servlet 对象出来;
        for (Class<Servlet> cls : allServletClasses) {
    // 这里是利用 java 中的反射特性做的
    // 实际上还得涉及一个类的加载问题,因为我们的类字节码文件,是按照约定的
    // 方式(全部在 WEB-INF/classes 文件夹下)存放的,所以 tomcat 内部是
    // 实现了一个自定义的类加载器(ClassLoader)用来负责这部分工作。
            Servlet ins = cls.newInstance();
            instanceList.add(ins);
        }
    // 调用每个 Servlet 对象的 init() 方法,这个方法在对象的生命中只会被调用这一次;
        for (Servlet ins : instanceList) {
            ins.init();
        }
// 利用我们之前学过的知识,启动一个 HTTP 服务器
// 并用线程池的方式分别处理每一个 Request
        ServerSocket serverSocket = new ServerSocket(8080);
// 实际上 tomcat 不是用的固定线程池,这里只是为了说明情况
        ExecuteService pool = Executors.newFixedThreadPool(100);
        while (true) {
            Socket socket = ServerSocket.accept();
// 每个请求都是用一个线程独立支持,这里体现了我们 Servlet 是运行在多线程环境下的
            pool.execute(new Runnable() {
                doHttpRequest(socket);
            });
        }
// 调用每个 Servlet 对象的 destroy() 方法,这个方法在对象的生命中只会被调用这一次;
        for (Servlet ins : instanceList) {
            ins.destroy();
        }
    }
    public static void main(String[] args) {
        new Tomcat().start();
    }
}

流程:

在Tomcat容器中,当接收到HTTP请求时,会创建相应的Servlet类实例来处理该请求。Tomcat使用了Java的反射机制来创建Servlet实例,并依赖于Servlet规范的生命周期方法来管理Servlet的生命周期。

## 初始化阶段:
Tomcat在启动时会扫描应用程序的部署描述符(如web.xml文件)来获取Servlet的配置信息。
根据配置信息,Tomcat会使用Java的反射机制动态加载Servlet类,并调用其无参构造方法创建Servlet实例。
创建Servlet实例后,Tomcat会调用Servlet的init()方法将Servlet初始化,并传递一个ServletConfig对象,其中包含了Servlet的配置参数。

## 请求处理阶段:
当接收到HTTP请求时,Tomcat会根据请求的URL匹配到对应的Servlet。
Tomcat会为每个请求创建一个独立的线程,该线程负责处理该请求。
Tomcat会调用Servlet的service()方法来处理请求,将请求和响应对象作为参数传递给service()方法。

## 生命周期管理:
在Servlet的整个生命周期中,Tomcat会根据Servlet规范的要求调用相应的生命周期方法。
在Servlet实例创建后,Tomcat会调用init()方法进行初始化。
当Tomcat关闭或重新加载Web应用程序时,会调用Servlet的destroy()方法进行销毁。
在运行期间,Tomcat会根据需要调用service()方法来处理请求。

使用Java的反射机制,Tomcat可以动态地加载和实例化Servlet类,而不需要直接在代码中进行显式的实例化。通过调用Servlet的生命周期方法,Tomcat能够管理Servlet的状态和资源,并在需要时创建、初始化和销毁Servlet实例。这种基于反射和生命周期方法的机制使Tomcat能够有效地处理Servlet请求,并提供高性能和可扩展性的Web应用程序容器。

优化性能:
  1. 调整Tomcat线程池大小:Tomcat默认的线程池大小为200,如果在高并发的情况下,可能会导致线程池资源不足,可以通过修改Tomcat的配置文件,调整线程池大小。
  2. 调整JVM内存分配:Tomcat在启动时会使用JVM内存来加载应用程序和处理请求。如果JVM内存分配不合理,可能会导致内存不足或内存泄漏,可以通过调整JVM内存分配参数,如-Xms和-Xmx。
  3. 使用缓存:Tomcat支持多种缓存技术,如内存缓存、磁盘缓存和分布式缓存等。通过使用缓存,可以减少应用程序对数据库和其他资源的访问,提高响应速度和并发访问量。
  4. 使用 CDN 加速静态资源:可以使用 CDN(内容分发网络)来加速静态资源的传输,减少服务器的负载,提高网站的访问速度。
  5. 启用静态资源缓存:可以通过在 web.xml 中配置 filter,启用静态资源缓存,减少服务器的负载,提高访问速度。

你可能感兴趣的:(java,前端,学习)