B/S 结构的通信原理
WEB 系统的访问过程
1:打开浏览器
2:找到地址栏
3:输入一个合法的地址
4:回车
5: 在浏览器上响应搜索内容
关于域名:
https://www.baidu.com/f
www.baidu.com 是一个域名
在浏览器地址栏上输入一个域名,回车后,域名解析器会将域名解析出来一个具体的IP地址和端口号等。
解析结果也许是: http://110.242.68.3:80/index.html
IP地址是啥?
计算机在网络当中的身份证号,同一个网络当中,IP地址是唯一的。
A计算机想要和B计算机通信,首先你需要知道B计算机的IP地址,有了IP地址才能建立连接
端口号是啥?
一个端口代表一个软件(一个端口代表一个应用,一个端口仅代表一个服务).
在一个计算机当中有很多软件,每个软件启动之后都有一个端口号。
一个WEB系统的通信原理?通信步骤:
第一步:用户输入网址(URL)
第二部域名解析器进行域名解析
第三步:浏览器在网络中搜索解析出的ip对应的主机,知道找到这台主机
第四步:定位对应ip的主机上的服务器软件,根据端口找到对应的服务器软件
第五步:服务器软件得知浏览器想要的资源
第六步:浏览器接收到服务器软件返回的资源
第七步:浏览器解析出服务器返回的资源,进行展示
Tomcat
tomcat 是一款开源免费的轻量级WEB服务器
tomcat 只实现了Servlet+jsp的规范
tomcat 是用java语言写的。
tomcat 想要运行,需要先有jre,所有要先安装JDK,配置java运行环境
启动Tomcat
bin目录下有一个文件:startup.bat 通过它可以启动tomcat服务器
xxx.bat 文件是一个什么文件?bat文件是windows操作系统专用的,bat文件是批处理文件,这种文件可以编写大量的windows的dos命令,然后执行bat文件,就相当于执行多个dos命令
xxx.sh 这个文件在windows下不可以执行,sh文件是linux操作系统专用的,sh文件可以编写大量的linux的shell命令,然后执行sh文件,就相当于执行多个shell命令
tomcat提供了bat和sh,说明tomcat服务器的通用性
分析startup.bat 可知,最终执行的是 catlina.bat 文件
启动Tomcat服务器只配置path对应的bin是不行的,还需要配置
JAVA_HOME和CATALINA_HOME(配置tomcat的根目录)
并将bin中的shutdown.bat 改名为stop.bat ,因为和Windows的关机命令冲突
关于tomcat的目录
bin:这个目录是tomcat服务器的命令文件存放的目录,比如,启动tomcat,关闭tomcat等等
conf:这个目录是tomcat配置文件的存放目录(server.xml中可以修改服务器的端口号,tomcat默认端口8080)
lib: 这个是tomcat服务器的核心程序目录,因为tomcat服务器是java语言写的,这里的jar包里面都是class文件
logs:tomcat的日志目录,tomcat服务器启动等信息都会在这个目录下生成日志文件
temp:tomcat服务器的临时目录,存储临时文件。
webapps:这个目录就是用来存放大量的webapp(web application)
work:这个目录是用来存放jsp文件翻译之后的java文件以及编译之后的class文件
开发带有Servlet的web App
开发步骤
1:在webapps目录下新建一个目录,起名crm(这个crm就是webapp的名字)。当然也可以是其他项目,银行系统创建一个bank
注意:crm就是webapp的根
2:在webapp的根下新建一个目录:WEB-INF
注意:这个目录的名字是Servlet规范中规定的,必须全部大写,必须一模一样。
3:在WEB-INF 目录下新建一个目录:classes
注意:这个目录必须是小写的classes。这个也是Servlet规范中规定的。(存放的是字节码文件)
4:在WEB-INF 目录下新建一个目录:lib
注意:这个目录不是必须的,但是如果一个webapp需要第三方jar包的话,这个jar包要放到这个lib目录下,这个目录的名字也不能随意些,必须是小写的lib,例如java语言连接数据库的驱动jar包。那么这个jar就应该放到这个lib目录下。这是Servlet规范中规定的。
5:在WEB-INF目录下新建一个文件:web.xml
注意:这个文件是必须的,这个文件名必须叫做web.xml.这个文件必须放在这里。一个合法的webapp,web.xml文件是必须的,这个web.xml文件就是一个配置文件,在这个配置文件中描述了请求路径和Servlet类之间的对照关系。
这个文件最好从其他的webapp中拷贝,最好别手写,没必要,直接复制。
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
metadata-complete="true">
</web-app>
6:编写一个java程序,这个小java程序也不能随意开发,这个小java程序必须实现Servlet接口。
这个Servlet接口不在jdk中(因为Servlet不是JavaSE了,Servlet)
Servlet接口是Oracle提供的
Servlet接口是javaEE规范中的一员
Tomcat服务器实现了Servlet规范,所以Tomcat服务器也需要使用Servlet接口。Tomcat服务器中应该有这个接口,Tomcat服务器的CATALINA_HOME/lib 目录下有一个servlet-api.jar之后,你会看到里面有一个Servlet.class 文件。
重点:从jarkartaEE9开始,Servlet接口全名变了:jakarta.servlet.Servlet
注意:编写java小程序的时候,java源代码位置无所谓,只需要将java源代码编译之后的class文件放到classes目录下即可。
7:编写HelloServlet
重点:怎么让Servlet编译通过呢?配置环境变量CLASSPATH
CLASSPATH=.;%JAKARTA_HOME%lib\servlet-api.jar
配置这个CLASSPATH跟tomcat能否运行没有关系,只是为了在文本编译器中使用servlet-api.jar中的类编译通过
HelloServlet.java
package com.bjpowernode.servlet;
import java.io.IOException;
import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.ServletConfig;
public class HelloServlet implements Servlet{
public void init(ServletConfig config) throws ServletException{
}
public void service(ServletRequest request,ServletResponse response)
throws ServletException,IOException{
System.out.println("My First Servlet,Hello Servlet");
}
public void destroy(){}
public String getServletInfo(){ return ""; }
public ServletConfig getServletConfig(){
return null;
}
}
8:将以上编译通过的class复制到WEB-INF/classes 目录下
9.编写web.xml,将servlet与浏览器path绑定
10.以后我们不需要编写main,Tomcat启动会自动启动main方法,我们只需要编写Servlet
总结:一个完整的webapp的目录结构
webapproot
|-------WEB-INF
|-------classes(存放字节码)
|-------lib(第三方jar包)
|-------web.xml(注册servlet)
|-------html
|-------css
|-------javascript
|-------image
.....
浏览器发送请求,到最终服务器调用servlet中的方法,是怎样的一个过程?(以下过程为粗糙的描述)
用户输入URL,或者直接点击超链接http://127.0.0.1:8080/crm/hello
然后tomcat服务器接收到请求,截取路径:/crm/hello
Tomcat服务器找到CRM项目
Tomcat服务器在web.xml文件中查找对应的/hello 对应的Servlet是com.bjpowernode.servlet.HelloServlet
Tomcat服务器通过反射机制,创建了com.bjpowernode.servlet.HelloServlet对象
Tomcat服务器调用com.bjpowernode.servlet.HelloServlet对象的service方法
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
metadata-complete="true">
<!--servlet 配置信息-->
<servlet>
<!--任何一个servlet都对应一个servlet-mapping-->
<servlet-name>hello</servlet-name>
<!--这里必须是带有包名的全限定类名-->
<servlet-class>com.bjpowernode.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--这里随便写,但是要和对应的servlet name相同-->
<servlet-name>hello</servlet-name>
<!--这个是浏览器中访问的路径,唯一要求要以 / 开头-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
10: 启动Tomcat服务器
11: 打开浏览器,在浏览器地址栏上输入一个URL,这个URL必须是:http://127.0.0.1:8080/crm/hello
非常重要的一件事:浏览器上的请求路径不能随便写,必须和url-pattern 中的path一样
关于JavaEE的版本
javaEE 目前最高版本不是JavaEE8
javaEE 被Oracle捐献了,Oracle将JavaEE捐献给了Apache
Apache把javaEE换名了,以后不叫javaEE了,以后叫做jakarta EE。
以后没有javaEE了,以后叫做jakartaEE了
javaEE8版本升级后不叫javaEE9 叫做jakartaEE9
javaEE8 对应的Servlet类名是:javax.servlet.Servlet
javaEE9 对应的Servlet类名是:
jakarta.servlet.Servlet(包名都换了)
如果之前使用的项目还是使用的javax.servlet.Servlet,那么项目无法直接部署到tomcat10以上了
jakartaEE9以上Servlet包名为 jakarta.servlet.Servlet
使用IDEA工具开发Servlet
1.New Project(习惯新建一个Empty Project),然后再空工程下新建Module(模块),不是必须的,可以直接新建project。这个EmptyProject 起名为javaweb不是必须的,只是一个项目名字而已)一般情况下新建的projec的名字最好和目录名字一致。
2.New Module
这里新建的是一个普通的java SE模块
这个Module自动会被放在javaweb目录下
Module 起名为servlet01
3.将模块变成javaEE模块。(让Model变成webapp的模块,符合webapp规范和servlet规范的Module)
在Module上点击右键:Add Framework Support
再弹出的窗口中选择Web Application(选择的是webapp的支持
选择这个webapp的支持后,IDEA会自动给你生成一个符合servlet规范的webapp目录结构。
重点,需要注意的: 在IDEA工具中根据Web Application模板生成的目录中有一个web目录,这个目录就代表webapp的根目录。
4. 根据Web Application生成的资源中有一个index.jsp文件,这里我选择删除这个index.jsp文件。
5. 编写Servlet
这时候发现Servlet.class 文件没有,将CATALINA_HOME/lib下的servlet-api.jar和jsp-api.jar 添加到classpath中(这里指的是IDEA classpath)
6. 在servlet 中编写业务代码(这里我们连接数据库)
7. 在WEB-INF目录下创建lib(这个目录名不可以随便写,必须是全部小写的lib),并且将连接数据库的驱动jar包放到lib目录下
8. 在web.xml 文件中完成StudentServlet类的注册。(请求路径和Servlet之间对应起来)
<?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>userlist</servlet-name>
<servlet-class>com.bjpowernode.servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userlist</servlet-name>
<url-pattern>/userlist</url-pattern>
</servlet-mapping>
</web-app>
9. 给一个HTML页面,在HTML页面中编写一个超链接,用户点击这个超链接,发送请求,Tomcat执行后台的StudentServlet。
student.html
这个文件不能放到WEB-INF目录里面,只能放到WEB-INF目录外面
Student.html内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
</head>
<body>
<!--/user表示项目名称,目前项目名无法动态获取,先写死 ,userlist代表web.xml中配置的servlet名称-->
<a href="/user/userlist">用户列表</a>
</body>
</html>
Servlet 生命周期
- 什么是Servlet的生命周期?
- Servlet对象什么时候被创建
- Servlet对象什么时候被销毁
- Servlet对象创建了几个?
- Servlet对象的生命周期表示:一个Servlet对象从出生到最后的死亡,整个过程是怎样的。
- Servlet对象由谁来维护?
- Servlet对象的创建,对象方法的调用,对象最终的销毁,javaweb程序猿是无权干预的。
- Servlet对象的生命周期是有Tomcat服务器(WebServer,例如Tomcat,jetty)全权负责的
- Tomcat服务器通常我们又称为WEB容器。
- Web容器来管理Servlet对象的死活
- 思考:我们自己new的Servlet对象受WEB容器的管理吗?
- 我们自己new的Servlet对象是不受WEB容器管理的。
- WEB容器创建的Servlet对象,这些Servlet对象都会被放到一个集合当中(HashMap),只能放到这个Map中的Servlet才能够被WEB容器管理,自己new的Servlet对象不会被WEB容器管理(自己new的servlet 对象不在这个容器当中)
- WEB容器底层应该有一个HashMap这样的集合,在这个集合当中存储了Servlet对象和请求路径之间的关系
- 研究:服务器在启动的时候,Servlet有没有被创建(默认情况下)?
- 经过测试服务器启动的时候Servlet并没有被实例化
- 这个设计是合理的。用户没有发送请求之前,如果提起那创建出来所有的Servlet对象,必然是耗费内存的,并且创建出来的Servlet对象没有用户访问 ,显然常见出来是浪费系统资源的
- 在servlet标签中添加子标签,在该标签中填写整数,越小的整数优先级越高
<?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>aservlet</servlet-name>
<servlet-class>com.bjpowernode.servlet.AServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>aservlet</servlet-name>
<url-pattern>/a</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>bservlet</servlet-name>
<servlet-class>com.bjpowernode.servlet.BServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>bservlet</servlet-name>
<url-pattern>/b</url-pattern>
</servlet-mapping>
</web-app>
-
Servlet对象生命周期
- 默认情况下服务器启动的时候Servlet并不会实例化
- 用户第一次发送请求的时候会依次执行 constructor -> init() -> service()
- 用户再次发送请求不会重新创建Servlet,会复用之前的Servlet,并且只会执行Servlet实例的service()方法
- Servlet 对象是单例的。但是要注意:Servlet对象是单实例的,但是Servlet并不符合单例模式。我们称为假单例。之所以是单例是因为Servlet的创建是Tomcat管理的,Tomcat只创建了一个,所以导致了单例,但是属于假单例。真单例模式,构造方法是私有的。
- 无参数方法,init方法只在第一次用户发送请求的时候执行,也就是说五参数构造只执行一次。init方法也只被Tomcat方法执行一次。
- 只要用户发送一次请求:service方法必然会被Tomcat请求一次。
- 关闭服务器的时候,会调用Servlet的destroy方法。
- Servlet的destroy方法只有在服务器关闭的时候被tomcat调用一次。
- 当destroy方法调用的时候,Servlet对象还存在,没有被销毁,destroy方法执行结束之后,Aservlet对象的内存才会被释放掉。
-
当我们Servlet类中编写一个有参数的构造方法,如果没有手动编写无参构造方法会有什么问题?
- 报错:500
- 注意:500是一个HTTP协议的错误代码
- 500一般情况下是因为服务端的java程序出现了异常,(服务器端的错误都是500错误;服务器内部错误)
- 如果没有无参数的构造方法,会导致500错误,无法实例化Servlet
- 所以,一定要注意,在Servlet开发当中,不建议程序员定义构造方法,因为定义不当,会导致Servlet无法实例化
-
思考:Servlet的无参数构造方法是在丢向第一次创建的时候执行,并且只执行一次,init方法也是在对象第一次创建的时候执行,并且只执行一次,那么这个无参数构造方法可以替代init方法吗?
- 不能。
- Servlet 规范中有要求:作为javaweb程序员,编写Servlet类,不建议手动编写构造方法,因为编写构造方法,很容易让无参构造方法消失,所以init又存在的必要。
-
init ,service ,destroy方法中使用最多的是哪个方法?
- 使用最多的是service方法,service方法一定要实现,因为service方法是处理用户请求的核心方法。
- 什么时候使用init方法
- 很少用
- 通常在init方法中做初始化操作,并且这个初始化操作只需要执行一次(例如初始化数据库连接池,初始化线程池)
- 什么时候使用destroy方法
- destroy方法也很少用
- 通常在destroy方法中,进行资源的关闭。马上对象就要被销毁了,还有没有关闭的资源可以关闭,没有保存的资源进行保存。
Servlet->GenericServlet(抽象类,解决空实现方法问题,不再需要实现所有方法)->
ServletConfig
- ServletConfig 是什么?
- ServletConfig 是一个接口,是Servlet规范中的一员
- 谁去实现了这个接口?Web服务器去实现了
- 一个Servlet对象中有一个ServletConfig对象,(Servlet和ServletConfig对象是一对一)
- ServletConfit对象是谁创造的?在什么时候创建?
Tomcat服务器(Web服务器)创建了ServletConfig对象,在创建Servlet对象的时候,同时创建了ServiceConfig对象
- ServletConfig 对象包装了哪些信息?
<servlet>
<servlet-name>aservlet</servlet-name>
<servlet-class>com.bjpowernode.servlet.AServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
- ServletConfig 对象包含的信息是<servlet>标签中配置的信息
Tomcat小猫咪解析web.xml文件后,将web.xml 文件中<servlet> 标签中的配置信息包装到ServletConfig对象中。
- ServletConfig对象中有哪些方法?
- getServletName() 对象<servlet-name>
- getInitParameterNames() 获取所有的<init-param>中的<param-name> 配置的值
- getInitParameter(String name) 跟据获取到的<param-name> 获取到<param-value>
- getServletContext()
ServletContext
-
ServletContext 是什么?
- ServletContext 是一个接口,是Servlet规范中的一员
-
谁去实现了这个接口?Web服务器去实现了
-
一个Servlet对象中有一个ServletConfig对象,(Servlet和ServletConfig对象是一对一)
-
ServletContext对象是谁创造的?在什么时候创建? Tomcat服务器(Web服务器)启动的时候创建了ServletContext对象,对于一个webapp来说,ServletContext对象只有一个,ServletContext对象在服务器关闭的时候销毁。
-
ServletContext对象怎么理解?
-
context是什么 意思? Servlet对象的环境。(Servlet对象的上下文对象) ServletContext对象其实对应的就是整个web.xml文件 ServletContext对象是所有Servlet对象共享的。
-