一. Tomcat安装和启动

  1. # 一. tomcat安装
  2. 1. 找到资料中 apache-tomcat-8.5.31-windows-64位.zip
  3. 2. 解压即可用
  4. 所在目录不要有中文和一些非法字符

1649294886512.png

# 二. tomcat的启动和关闭
1. 启动
    1). tomcat/bin/startup.bat 双击
    2). 会出现一个dos窗口: 上面是tomcat运行输出的信息
2. 关闭
    1). 方式一: 关闭dos窗口 (拔电源)
    2). 方式二: tomcat/bin/shutdown.bat 单击 (正常关闭)

3. 启动常见的问题:
    1). 闪退 : 点击startup.bat之后,dos窗口一闪即过
        I. 原因: JDK版本不对(JDK8)或JAVA_HOME配置不对
            (看笔记)
    2). 运行一会退出:
        I. 主要原因: 端口冲突
            tomcat已经启动了,占用了8080端口
            再次启动tomcat,就会端口冲突退出
        II. 原因二: 端口冲突
            其他应用占用了8080端口
            启动tomcat,也会端口冲突退出
            a. 解决方案一: 关闭占用8080端口的程序(看笔记)
            b. 解决方案二: 修改tomcat的默认端口
# 三. tomcat 发布资源 (webapps目录)
1. 操作
    1). 往tomcat/webapps目录下放了 a/hello.html
        (发布资源)
    2). 启动tomcat
        (启动服务器)
    3). 浏览器访问地址 http://localhost:8080/a/hello.html
        (访问服务器资源)
2. 原理:
    1). url格式
        协议://ip:port/资源位置?参数
        a. 协议: 是两个程序传输数据的规则 (tomcat使用http协议)
        b. ip : 服务器程序所在的计算机ip (localhost: tomcat装在本机)
        c. port :服务器程序占用的port (tomcat占用8080端口)
        d. 资源位置: 有资源在位置 a/hello.html中 (资源需要放在tomcat/webapps)
    2). 交互过程
        a. 浏览器发送一个请求给服务器(tomcat)
        b. 服务器接收到请求之后,将浏览器需要的资源响应给浏览器
        c. 浏览器接收到服务器响应的资源之后,进行显示
3. 重点:
    1). tomcat默认发布资源的路径: webapps目录
4. 扩展:省略规则
    1). webapps/ROOT目录 是tomcat发布资源的根目录 (强制不写)
        I. 发布  webapps/ROOT/hi.html
        II. 访问  http://localhost:8080/hi.html
        III. 其他问题
            直接发布在webapps下的资源时访问不到的
            http://localhost:8080/a.html 这是访问ROOT下的资源
    2). 资源名为index,可以省略不写
        I. 发布  webapps/a/index.html
        II. 访问
            http://localhost:8080/a/ (省略不写)
            http://localhost:8080/a/index.html(完整写法)
        III. 其他问题
            a. 省略不写,资源index后缀名必须为 html > htm > jsp (优先级)
                    (tomcat/conf/web.xml)    
                  <welcome-file-list>
                    <welcome-file>index.html</welcome-file>
                    <welcome-file>index.htm</welcome-file>
                    <welcome-file>index.jsp</welcome-file>
                </welcome-file-list>
            b. 当我们访问http://localhost:8080/,你会看到tomcat欢迎页
                 tomcat/webapps/index.jsp(欢迎页)

1649297396062.png

# 四. tomcat 发布资源 (虚拟路径)
1. 操作
    I. 打开 tomcat/conf/server.xml文件,进行编辑
        <Context path="mypro" docBase="C:\test"/>
        1). 虚拟路径 : mypro (可以自定义)
        2). 真实路径 : C:\test
        3). 两个路径之间存在映射关系
            String mypro = "C:\test";
            访问mypro,就相当于访问C:\test
    II. 发布资源
        在C:\test目录下放了一个b.html资源
    III. 重启tomcat,让tomcat重新加载配置    
    IV. 浏览器访问 http://localhost:8080/mypro/b.html
        tomcat会响应 C:\test\b.html资源

2. 对比webapps目录发布, 虚拟路径发布方式,可以在任意位置发布资源

1649300697715.png

Idea配置中Tomcat

1649300890872.png

1649301001161.png

1649301168839.png

1649301229237.png

Idea创建maven的web工程

1649301423668.png

1649301478071.png

1649301494771.png

1649301537790.png

1649301564332.png
1649301662631.png

1649301720774.png
1649301786608.png
1649301821617.png
1649301911102.png

# web工程目录介绍
1. java目录 : 写java代码
2. resources目录 : 配置文件
3. webapp目录
    1). WEB-INF/web.xml 文件 (注意: WEB-INF是浏览器访问不到,资源别放这里)
            web工程配置文件
    2). 静态资源可以直接放到这里
        html,css,js,图片等...

在Idea的tomcat中发布web工程

1649302404444.png

1649302459065.png

1649302530653.png

1649302601374.png

1649302659029.png

1649302768912.png

1649313839190.png

二. Servlet入门

1. Servlet入门案例

1.1代码编写步骤

1649314636121.png

# 代码编写步骤
0. 基于web工程
1. pom.xml文件中添加依赖Servlet
2. 编写一个类,实现Servlet接口
3. 配置web.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>day15-demo01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--
        web工程打包方式
    -->
    <packaging>war</packaging>
    <dependencies>
        <!--
            Servlet的jar包
                1. 版本3.0以上
                2. scope: provided (maven高级学习: 作用域)
                    避免跟tomcat冲突
        -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>
/*
    编写一个类,实现Servlet接口,并在service方法中编写代码

 */
public class MyServlet implements Servlet {

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        //控制台打印
        System.out.println("MyServlet被访问了");
        //网页上显示
        res.getWriter().println("hello servlet");
    }

    @Override
    public void init(ServletConfig config) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>MyServlet01</servlet-name>
        <servlet-class>com.itheima01.servlet.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet01</servlet-name>
        <url-pattern>/ms</url-pattern>
    </servlet-mapping>
</web-app>

1.2 演示步骤

1. 将此工程发布到tomcat上
2. 启动tomcat
3. 打开浏览器访问: http://localhost:8080/day15-demo01/ms
    就会看到网页上显示 hello servlet  -> MyServlet的service方法调用了

1649315055078.png

1649315151889.png

1.3 运行原理

1649316607954.png

1649316661366.png

2. Servlet的生命周期方法

package com.itheima02.life;

import javax.servlet.*;
import java.io.IOException;

/**
 * TODO Servlet的生命周期方法
 *  1. 生命周期: 从创建到销毁的整个过程
 *  2. 生命周期方法
 *      1). init (初始化)
 *          I. 执行时机: Servlet对象创建时调用,只执行一次
 *          II. 默认: Servlet第一次被访问时, 对象创建
 *          III. 作用: 初始化数据,加载资源
 *      2). service (服务)
 *          I. 执行时机: 每次访问,都会执行一次
 *          II. 作用: 处理业务
 *      3). destroy (销毁)
 *          I. 执行时机:  Servlet对象在被销毁时调用,只执行一次
 *          II. 默认: tomcat关闭之前,会先销毁Servlet对象
 *          III. 作用: 资源释放,将数据存储起来
 *
 *  3. 方法执行时机:
 *      1). 浏览器第一次访问LifeServlet (tomcat会创建LifeServlet对象)
 *          init
 *          service
 *      2). 浏览器再次访问LifeServlet
 *          service
 *      3). 关闭tomcat
 *          destroy
 */
public class LifeServlet implements Servlet {
    //Servlet的方法也是由tomcat调用的
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init");
    }
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("service");
    }
    @Override
    public void destroy() {
        System.out.println("destroy");
    }
    @Override
    public ServletConfig getServletConfig() {
        System.out.println("getServletConfig");
        return null;
    }
    @Override
    public String getServletInfo() {
        System.out.println("getServletInfo");
        return null;
    }


}

web.xml

 <servlet>
        <servlet-name>LifeServlet</servlet-name>
        <servlet-class>com.itheima02.life.LifeServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LifeServlet</servlet-name>
        <url-pattern>/LifeServlet</url-pattern>
    </servlet-mapping>

启动加载

 /* TODO 4. 启动加载
 *      1). 问题: 如果我们真的用init方法来初始化数据, 那么第一个访问的用户需要等待比较久的时间!
 *      2). 解决:
 *                  默认Servlet第一次被访问时, 对象创建
 *              改成 tomcat启动时,就让Servlet对象创建
 *      3). 实现:
 *              load-on-startup
 */
public class LifeServlet implements Servlet {
    //Servlet的方法也是由tomcat调用的
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init");
    }
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("service");
    }
    @Override
    public void destroy() {
        System.out.println("destroy");
    }
    @Override
    public ServletConfig getServletConfig() {
        System.out.println("getServletConfig");
        return null;
    }
    @Override
    public String getServletInfo() {
        System.out.println("getServletInfo");
        return null;
    }


}

web.xml

<servlet>
        <servlet-name>LifeServlet</servlet-name>
        <servlet-class>com.itheima02.life.LifeServlet</servlet-class>
        <!--
            启动加载: load-on-startup
            1. 内容是整数 n
            2. 如果n<0 , 默认servlet对象在第一次访问时才创建(默认 n = -1)
            3. 如果n>=0, 就是tomcat启动时就会创建servlet对象
                数字越小, 越早创建
        -->
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>LifeServlet</servlet-name>
        <url-pattern>/LifeServlet</url-pattern>
    </servlet-mapping>

3. Servlet的体系结构

快捷键:
    1. ctrl + alt + u : 查看一个类的继承结构图
    2. ctrl + h : 这个类的简化版继承结构(类)

1586832839002.png

3.1 GenericServlet

1. 问题: 
    Servlet中使用频率最高,最重要的方法是service方法(大部分场景)
    但是我们每次编写Servlet实现类,都是直接实现Servlet接口,重写5个抽象方法(太冗余了)

2. 需求: 如果我们以后编写Servlet实现类,只要重写service方法就好了
3. 解决:
        1). 建立一个抽象类GenericServlet, 继承Servlet接口,重写除了service之外的四个抽象方法,空实现    
        2). 以后编写其他Servlet,只要继承 GenericServlet, 这时候就只要重写service方法

4. 发现 : 很巧, 开发包已经有了这个类GenericServlet

① 编写普通java类,继承GenericServlet抽象类

public class GoodServlet extends GenericServlet {

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("GoodServlet被访问");
    }

}

② 配置web.xml

    <servlet>
        <servlet-name>GoodServlet</servlet-name>
        <servlet-class>com.itheima03.generic.GoodServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GoodServlet</servlet-name>
        <url-pattern>/goodServlet</url-pattern>
    </servlet-mapping>

3.2 HttpServlet

1. 问题: 
      我们在前端的form表单中,method属性, 学习过有两种常用的请求方式(get/post)
          1). 请求 理解成 付款, 请求方式 理解成 付款方式
        2). get请求方式 -> 微信付款    post请求方式 -> 支付宝付款
        3). 两个请求方式有区别 -> 微信付款和支付宝付款有区别(微信的手续费比较高)
      我们现在的service方法是这样的: 用户发送请求,无论是什么请求方式,都会统一的执行service方法, 我们无法很好的区别是哪一种请求方式

2. 需求: 我们如果想确切的知道是哪一种请求方式,必须要先了解HttpServlet

3. 解决:  HttpServlet

① 编写前端html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--
        form表单中,点击提交按钮,就会将数据提交到action地址
        1. action属性: 服务器的地址
        2. method : 请求方式
    -->
        <h1>post请求</h1>
    <form action="Demo02Servlet" method="post">
        <input type="submit">
    </form>
    <h1>get请求</h1>
    <form action="Demo02Servlet" method="get">
        <input type="submit">
    </form>
</body>
</html>

② 编写普通java类,继承HttpServlet抽象类

package com.itheima03;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
    TODO:
        1. 当前类继承 HttpServlet
        2. 并重写doGet和doPost方法
 */
public class Demo02Servlet extends HttpServlet {

    //所有的请求都会被service方法所接收

    //如果请求方式是get请求, service方法底层调用doGet
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
    }
    //如果请求方式是post请求, service方法底层调用doPost
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost");

    }
}

③ 配置web.xml

  <servlet>
        <servlet-name>Demo02Servlet</servlet-name>
        <servlet-class>com.itheima03.Demo02Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo02Servlet</servlet-name>
        <url-pattern>/Demo02Servlet</url-pattern>
    </servlet-mapping>

三. 疑问

3.1 web工程

# java工程
1. 有main方法 
2. 打包方式: jar包
3. java工程可以独立运行
# web工程
1. 没有main方法
2. 打包方式: war包
3. web工程不可以独立运行,运行需要依赖web服务器(tomcat)

3.2 静态资源发布

1649323466272.png

3.3 浏览器缓存

# 浏览器的缓存机制
1. 浏览器为了提升访问效率,有可能将访问到的资源缓存起来
    http://localhost:8080/xx/ -> index.html (内容是index1)
    可能会缓存起来
2. 浏览器再次访问http://localhost:8080/xx/ -> index.html(内容是index2) , 就可能不会从服务器重新加载这个资源,而是将之前的缓存读取出来
3. 问题: 明明服务器的资源更新了,也重启了,浏览器读到的依然是的旧的数据
4. 解决: 清除浏览器的缓存,让浏览器硬性重新加载

1649324826374.png

四. 资源的路径访问规则

如果我们不知道请求方式是什么,默认是get

1649325418660.png

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <!--
        TODO 浏览器向服务器发送请求有很多种方式
        1. 浏览器地址栏直接输入 : get
        2. a标签 : get
        3. form标签 : 默认get (能够指定post方式)
             如果你不知道是什么请求方式,默认就是get

       TODO: 相对路径和绝对路径
        1. 绝对路径: 包含根路径
        2. 相对路径:  相对自身而言的路径
            i  ./ 表示当前路径 可以省略的
            ii ../ 上一级路径

            例子:
                当前路径(index.html) : http://localhost:8080/xx/index.html
                目标路径 :             http://localhost:8080/xx/MyServlet
    -->
    <a href="MyServlet">访问MyServlet</a> <br>
    <form action="MyServlet" method="post">
        <input type="submit">
    </form>
    <hr>
    <a href="http://localhost:8080/xx/MyServlet">绝对路径访问</a> <br>
    <a href="./MyServlet">相对路径访问</a> <br>
    <a href="MyServlet">相对路径访问</a> <br>


</body>
</html>