JavaWeb01
一、系统架构
1、两种常见架构
2、B/S架构的通信原理
域名解析器进行域名解析:http://110.242.68.3:8080/index.html
浏览器收到来自服务器响应的代码(HTML、CSS、JavaScript)
二、服务器软件
1、常见的服务器软件
Web服务器:Tomcat(又称catalina)、jetty
应用服务器:JBoss、WebLogic、WebSphere
Web服务器只实现了13个规范中的Servlet和JSP这两个
2、Tomcat
是Apache软件基金会的开源项目,Tomcat是用Java语言写的
work:存放JSP文件翻译后的Java文件以及编译后的class文件
通过startup.bat 启动(在这个脚本中会调用catalina.bat)
catalina.bat文件中有一行:MAINCLASS=org.apache.catalina.startup.Bootstrap
启动Tomcat服务器就是运行一个Java程序,就是执行main方法
需要配置JAVA_HOME(JDK的根)和CATALINA_HOME(Tomcat的根)
三、Web应用
1、创建一个简单的Web应用
访问http://localhost:8080/oa/test.html
2、动态网页
一个路径对应一个资源,静态资源(静态页面)或者动态资源(Java小程序)
3、B/S架构的角色和协议
一个Web应用既可以运作在Tomcat上,也可以运行在jetty上
b. Browser 和 webServer 之间:http协议(超文本传输协议)
四、Servlet
1、模拟Servlet本质
(1)SUN公司:指定Servlet规范(一个Java接口类以及其他规范)
(2)webapp开发者:编写一些XxxServlet类实现Servlet接口,编写配置文件配置资源路径和XxxServlet的映射关系
(3)webServer开发者:编写程序,解析配置文件,识别资源路径,调用对应的XxxServlet类
2、第一个Servlet程序开发步骤
(1)在webapps目录下新建一个文件夹命名为test(webapp的名称)
这个test文件夹就是这个webapp的根
(2)在webapp的根下新建一个目录WEB-INF(这是Servlet中规定的)
(3)在WEB-INF目录下新建一个目录classes(用来存放Java编译后的字节码文件)
(4)在WEB-INF目录下新建一个目录classes(用来存放依赖的第三方jar包)
(5)在WEB-INF目录下新建一个文件web.xml(这是一个配置文件)
web.xml中的内容最好从其他webapp的配置文件中直接拷贝
(6)编写Java小程序,实现Servlet接口
Servlet接口不在JDK中,而是属于JavaEE
JavaEE8及之前,全类名为javax.servlet.Servlet
JakartaEE9及之后,全类名为jakarta.servler.Servlet
Tomcat服务器实现了Servlet规范,所以Tomcat服务器中有这个接口
CATALINA_HOME/lib/servlet-api.jar 解压后里面有一个 Servlet.class
(7)编译我们编写的HelloServlet
配置环境变量 CLASSPATH=.;C:\dev\apache-tomcat-10.0.12\lib\servlet-api.jar(对应Servlet接口所在的jar包)
这个环境变量和Tomcat服务器的运行没有关系,只是为了编译HelloServlet
(8)将编译后的HelloServlet.class文件拷贝到classes目录下
(9)在web.xml文件中编写配置信息,建立请求路径和Servlet实现类的映射关系
这一步称为:在web.xml文件中注册Servlet类
(10)启动Tomcat服务器
(11)在浏览器中输入对应的URL(请求资源路径要带上项目名)
3、webapp的目录结构
webapproot|----WEB-INF|----classes|----lib|----web.xml|----html|----css|----javascript|----image
......
4、在集成开发环境中开发Servlet的步骤
(1)创建一个空项目
(2)在这个项目中创建一个普通的JavaSE模块
(3)将这个模块变成JavaEE模块
单击模块,双击shift,输入add framework,选择web应用
将会自动创建一个符号Servlet规范的webapp目录结构
(4)可选:先暂时删除index.jsp文件
(5)编写HelloServlet类实现Servlet接口
将CATALINA_HOME\lib目录的servlet-api.jar和jsp-api.jar添加到模块的依赖中
实现接口中的五个方法
(6)在service方法编写业务代码
(7)在WEB-INF目录下新建lib目录,引入连接数据库驱动的jar包
(8)在web.xml文件中注册Servlet类
(9)编写一个html页面,写一个超链接(要带上应用名称),链接到HelloServlet类的资源路径
(10)用IDEA工具关联到Tomcat服务器,将当前的Web应用部署上去
(11)启动Tomcat服务器,打开浏览器输入URL
5、Servlet对象的生命周期(创建和销毁的时机)
(1)Web容器
Servlet对象的生命周期是由Tomcat服务器(也叫Web容器)完全负责的
Web容器创建的Servlet对象会被放到一个集合(HashMap)中,被Web容器管理
如果自己new一个Servlet对象,不会被Web容器管理
Web容器底层有一个Map集合,存储了资源路径和XxxServlet类的映射关系
(2)服务器启动时
先解析web.xml文件,建立资源路径和XxxServlet类的映射关系,存到Map集合
服务器启动时不会创建Servlet对象
如果想让它创建,在注册某个Servlet对象时加上<load-on-startup>1</load-on-startup>即可
中间的填一个整数代表创建顺序的优先级,数字越小优先级越高
(3)用户第一次请求时
创建Servlet对象,紧接着执行init方法(用来初始化),再调用service方法
再发送请求后,只执行service方法
说明构造方法和init方法只被调用一次,Servlet对象是单例的
但是Servlet类并不符合单例模式,称之为假单例(真单例模式的构造方法是私有的)
(4)服务器关闭时
调用Servlet对象的destroy方法(此时对象还没有被销毁)
6、关于Servlet接口中的各个方法
(1)init方法:在Servlet对象创建后执行,且只执行一次
Servlet规范不建议手动编写构造方法
如果手动编写有参构造方法,则不会自动提供无参构造,可能导致无法创建对象
初始化操作(如初始化数据库连接池)通常放在init方法中
(2)service方法:用来处理用户请求的核心方法
(3)destroy方法:在Servlet对象销毁前执行,且只执行一次
该方法主要用于关闭资源或者保存资源等
7、使用适配器设计模式改造Servlet接口
(1)基本步骤
由于Servlet接口中service方法很常用,其他方法很少用
编写一个GenericServlet类实现Servlet接口,实现Servlet接口的所有方法
这个类是抽象类,其中service方法是抽象方法
以后编写的所有Servlet类都继承GenericServlet类,而不是实现Servlet接口
(2)改造优化
init方法的参数是ServletConfig对象,这个对象由Tomcat服务器创建并传入init方法
这个对象在service方法或其他方法中可能会用到,因此写成GenericServlet类的成员变量config
在init方法中为成员变量config赋值
自己编写的Servlet类可能要重写init方法,可能会覆盖GenericServlet类的init方法
因此在GenericServlet类写一个重载的init方法供子类重写
注意:GenericServlet类不需要我们自己实现,jakarta.servlet包中有
在GenericService类中还有一些扩展方法,即父接口中没有的方法
public abstract class GenericServlet implements Servlet {private ServletConfig config;@overridepublic final void init(ServletConfig config) throws ServletException {this.config = config;this.init(); // 调用init方法}// 这个方法供子类重写public void init() {}
}
8、ServletConfig接口
(1)jakarta.servlet.ServletConfig 这个接口是Servlet规范中的一员
org.apache.catalina.core.StandardWrapperFacade 这个类实现了ServletConfig接口
即Tomcat服务器(或其他的Web服务器)实现了Servlet接口
(2)一个Servlet对象对应一个ServletConfig对象
Tomcat服务器在创建Servlet对象时,同时创建ServletConfig对象,并作为参数传入init方法
(3)ServletConfig对象是Servlet的配置信息对象
其中包装的是web.xml文件中<servlet></servlet>标签中的配置信息
Tomcat服务器解析web.xml文件后,将相应的配置信息封装到ServletConfig对象中
(4)Servlet接口中的方法
<servlet><servlet-name>test</servlet-name><servlet-class>com.example.TestServlet</servlet-class><!--这里可以配置一个Servlet对象的初始化信息--><init-param><param-name>driver</param-name><param-value>com.mysql.cj.jdbc.Driver</param-value></init-param><init-param><param-name>url</param-name><param-value>jdbc:mysql://localhost:3306/mydatabase1</param-value></init-param>
</servlet>
<servlet-mapping><servlet-name>test</servlet-name><url-pattern>/test</url-pattern>
</servlet-mapping>
<init-param/>标签中是初始化参数,会被Tomcat封装到ServletConfig对象中
通过ServletConfig接口中的getInitParameterNames和getInitParameter方法可以获取
GenericServlet类中也有这两个方法
9、ServletContext接口(也叫应用域)
(1)该接口是Servlet规范的一员,Tomcat服务器(Web服务器)实现了该接口
org.apache.catalina.core.ApplicationContextFacade 这个类实现了ServletContext接口
(2)ServletContext对象在Web服务器启动时由服务器创建,在服务器关闭时销毁
对于一个webapp而言,ServletContext对象只有一个
即:在同一个webapp中,所有的Servlet对象共享一个ServletContext对象
一个ServletContext对象对应一个web.xml文件
(3)ServletContext称为Servlet对象的上下文对象
(4)ServletContext接口中的常用方法
public String getInitParameter(String name); // 通过初始化参数的name获取对应的value
public Enumeration<String> getInitParameterNames(); // 获取所有的初始化参数的name获取的是以下(全局)配置信息(不包括servlet标签内的):
<context-param><param-name>pageSize</param-name><param-value>10</param-value>
</context-param>
<context-param><param-name>startIndex</param-name><param-value>0</param-value>
</context-param><servlet>...</servlet>
servlet标签内的(局部)配置信息由ServletConfig的这两个方法来获取public String getContextPath(); // 获取应用的根路径,如/xmm
// 在Java代码中,不要将应用的根路径写死,因为部署的时候可能会更改项目名public String getRealPath(String path); // 获取文件的真实路径(绝对路径)
传参可以传入"/index.html",这里的"/"表示当前webapp的根
也可以传入"index.html",会自动从跟下开始查找这个文件// 通过ServletContext对象记录日志
// 会记录到 CATALINA_HOME/logs
// 注意:IDEA工具可以建多个Tomcat服务器,因此日志不一定在自己的Tomcat根目录
public void log(String msg);
public void log(String message, Throwable t);
补充:Tomcat服务器的logs目录下的日志文件
catalina.yyyy-MM-dd.log 服务器Java程序运行的控制台信息
localhost.yyyy-MM-dd.log 是ServletContext对象的log方法记录的日志信息
localhost_access_log.yyyy-MM-dd.txt 是访问日志
(5)如果一些数据被多个Servlet共享,且几乎不用修改,数据量不大,可以放到ServletContext对象中
public void setAttribute(String name, Object value); // 存
public Object getAttribute(String name); // 取
public void removeAttribute(String name); // 删
10、Servlet的继承结构
我们自己编写的Servlet类,一般不会直接继承GenericServlet类
因为B/S架构是基于HTTP协议的,Servlet规范为HTTP协议准备了一个类HttpServlet
我们编写的Servlet类要继承HttpServlet类
继承结构:
jakarta.servlet.Servlet
jakarta.servlet.GenericServlet
jakarta.servlet.http.HttpServlet