一. Tomcat安装和启动
# 一. tomcat安装
1. 找到资料中 apache-tomcat-8.5.31-windows-64位.zip
2. 解压即可用
所在目录不要有中文和一些非法字符
# 二. 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(欢迎页)
# 四. 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目录发布, 虚拟路径发布方式,可以在任意位置发布资源
Idea配置中Tomcat
Idea创建maven的web工程
# web工程目录介绍
1. java目录 : 写java代码
2. resources目录 : 配置文件
3. webapp目录
1). WEB-INF/web.xml 文件 (注意: WEB-INF是浏览器访问不到,资源别放这里)
web工程配置文件
2). 静态资源可以直接放到这里
html,css,js,图片等...
在Idea的tomcat中发布web工程
二. Servlet入门
1. Servlet入门案例
1.1代码编写步骤
# 代码编写步骤
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方法调用了
1.3 运行原理
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 : 这个类的简化版继承结构(类)
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 静态资源发布
3.3 浏览器缓存
# 浏览器的缓存机制
1. 浏览器为了提升访问效率,有可能将访问到的资源缓存起来
http://localhost:8080/xx/ -> index.html (内容是index1)
可能会缓存起来
2. 浏览器再次访问http://localhost:8080/xx/ -> index.html(内容是index2) , 就可能不会从服务器重新加载这个资源,而是将之前的缓存读取出来
3. 问题: 明明服务器的资源更新了,也重启了,浏览器读到的依然是的旧的数据
4. 解决: 清除浏览器的缓存,让浏览器硬性重新加载
四. 资源的路径访问规则
如果我们不知道请求方式是什么,默认是get
<!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>