JavaWeb:是用Java技术来解决相关web(Web就是在Http协议基础之上, 利用浏览器进行访问的网站)互联网领域的技术总和.
1、什么是Servlet
Servlet是一个JavaEE的组件,Servlet是一个程序(类),只不过必须要遵循Servlet的规范,必须实现Servlet接口
Servlet也是JavaEE中的一个规范,服务器其实是对Servlet的实现。
Java Servlet(Java服务器小程序)是一个基于Java技术的Web组件,运行在服务器端,它由Servlet容器所管理,用于生成动态的内容。即 运行在服务器端以多线程的方式处理客户端请求的小程序。
2、Servlet容器
Servlet容器也叫做Servlet引擎,是Web服务器或应用程序服务器的一部分,Servlet没有main方法,不能独立运行,它必须被部署到Servlet容器中,由容器来实例化和调用 Servlet的方法,Servlet容器在Servlet的生命周期内包容和管理Servlet。管理和运行Servlet/JSP的容器也称为Web容器。
Web容器的产品:Tomcat,JBoss,WebSphere,WebLogic 等等
3、Servlet可以完成以下功能
1)创建并返回客户请求的动态HTML页面
2)创建可以嵌入到 HTML页面的HTML片段
3)与其他服务器(如数据库或基于Java的应用程序)进行通信
1、新建一个 dynamic web project动态的 JavaWeb项目
2、新建一个 DemoServlet类
Servlet的含义:运行在服务器端的以多线程的方式处理客户端请求的小程序
可以让 DemoServlet类去 implements Servlet接口或 extends GenericServlet类或 extends HttpServlet类
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServlet implements Servlet{
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("destroy");
}
}
3、在web.xml中注册Servlet的实现类
DemoServlet
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
HelloServlet
cn.jq.demo.HelloServlet
HelloServlet
/hello
4、项目部署到服务器
浏览器访问:http://127.0.0.1:8080/DemoServlet/hello,然后 stop服务器
Servlet的生命周期:Servlet对象的创建,初始化,运行,销毁操作的整个过程。即阐述Servlet从产生到毁灭的整个过程。
服务器(Tomcat)管理了Servlet对象的生命周期,Servlet的创建,初始化,运行,销毁行为的整个过程都是由Tomcat来负责调用的,
1、新建一个 LifeServlet类,注册同上
public class LifeServlet implements Servlet{
public LifeServlet() {
System.out.println("构造方法");
}
// 初始化阶段
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init");
}
// 获取Servlet的配置信息对象
@Override
public ServletConfig getServletConfig() {
return null;
}
// 响应客户请求阶段
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service");
}
// 获取Servlet的信息(作者,版权等)
@Override
public String getServletInfo() {
return null;
}
// 终止阶段
@Override
public void destroy() {
System.out.println("destroy");
}
}
2、Servlet生命周期相关方法
1)Servlet对象的构造方法
最先被执行,构造方法被执行意味着创建实例,且只会被执行一次,意味着Servlet是单例的,在整个Servlet容器中每个具体的Servlet实现类都只有一个实例!
2)init方法
在一个Servlet的生命周期中,构造方法执行之后,马上被执行,且只会执行一次,之后无论用户执行多少次请求,都不会在调用该方法。
关于init方法的执行时机,有两种方式可选:
servlet默认是在用户第一次访问的时候创建而且只创建一个对象 是单例模式的(保证一个类只有一个对象产生),
也可以设置Servlet容器启动时自动装载某些Servlet,这时创建的servlet对象也是单例模式的。 实现它只需要在web.XML文件中的
LifeServlet
cn.jq.demo.LifeServlet
1
3)service方法
当一个客户请求该Servlet时,实际的处理工作全部有service方法来完成,service方法用来处理客户端的请求,并生成格式化数据返回给客户端。
每一次请求服务器都会开启一个新的线程并执行一次service方法,service是由web容器来调用的。
4)destroy方法
该方法在整个生命周期中,也是只会被调用一次,在Servlet对象被销毁是调用,在servlet中,我们可以做一些资源的释放等操作,执行destory方法之后的servlet对象,会等待jvm虚拟机的垃圾回收机制择时回收。
总结:Servlet的生命周期:构造器 -> init方法 -> service方法(循环)-> destroy方法
注意:
1)Servlet类的构造器必须使用 public修饰
2)Servlet类必须是无参数构造器(不写默认是)。原因:底层创建Servlet对象是 Class.newInstance()方式,必须有公共的无参数构造器
对上面的访问大致分析 Servlet的请求流程:
1、浏览器访问发送请求:http://127.0.0.1:8080/DemoServlet/life
2、Tomcat 解析请求:/DemoServlet/life
上下文路径:/DemoServlet 资源名称: /life
3、解析Tomcat根 /cong/server.xml文件,获取其中所有的
4、从该Web项目的根路径下找到 /WEB-INF/web.xml 文件
5、读取 web.xml文件,获取所有的
找到:进入第6步 找不到:报 404错误
6、通过资源名称 /life,找到当前Servlet的全限定名:cn.jq.demo.LifeServlet
7、从Servlet的实例缓存池(Map集合)中获取 cn.jq.demo.LifeServlet对应的对象
Map
若为第一次请求:进入第8步,否则:进入第11步。
8、使用反射创建Servlet对象
Servlet obj = Class.forName("cn.jq.demo.LifeServlet").newInstance();
9、把创建的Servlet对象存储到Servlet实例缓存池中,供下次请求使用。
cache.put("cn.jq.demo.LifeServlet", obj );
10、Web容器创建 ServletConfig对象,并调用 init方法,来完成初始化操作
11、Web容器容器创建 ServletRequest和 ServletResponse对象,并调用service方法处理请求
12、在service方法中,通过ServletResponse对象对当前请求的客户端作为响应。
1、ServletConfig 接口:表示当前的 Servlet的配置信息对象
在web.xml中,每个Servlet可以单独配置/获取其初始化的配置信息。可以用一个或多个
1)Servletconfig接口的方法:
String |
getInitParameter(String name) Gets the value of the initialization parameter with the given name. |
Enumeration |
getInitParameterNames() Returns the names of the servlet's initialization parameters as an |
ServletContext |
getServletContext() Returns a reference to the |
String |
getServletName() Returns the name of this servlet instance. |
2、ServletCotext接口:很重要,先简单认识一下
如果多个Servlet有公共的初始化参数时,此时得使用全局的初始化参数
在web.xml中,可以用一个或多个
1)ServletContext域对象可以在整个web应用范围内共享数据
作用范围:整个web应用范围内共享数据
生命周期:当服务器启动web应用加载后创建出ServletContext域对象。当web应用被移除出容器或服务器关闭时随着web应用的销毁域销毁。
2)ServletContext接口的方法:
方法很多,具体查看API:https://docs.oracle.com/javaee/7/api/
3、获取初始化参数
encoding
GBK
password
123456
LifeServlet
cn.jq.demo.LifeServlet
encoding
UTF-8
username
admin
public class LifeServlet implements Servlet {
private ServletContext servletContext;
// 初始化阶段
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init");
//获取当前Servlet在web.xml中配置的名字
System.out.println(config.getServletName());
//获取当前Servlet指定名称的初始化参数的值
String usernameValue = config.getInitParameter("encoding");
System.out.println(usernameValue);
//获取当前Servlet所有初始化参数的名字
Enumeration enumeration = config.getInitParameterNames();
while (enumeration.hasMoreElements()) {
String name = (String) enumeration.nextElement();
String value = config.getInitParameter(name);
System.out.println(name + ":" + value);
}
//获取代表当前web应用的ServletContext对象
this.servletContext = config.getServletContext();
System.out.println(servletContext);
}
// 响应客户请求阶段
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service");
// 获取单个的Context里面的初始化参数
String value1 = servletContext.getInitParameter("encoding");
String value2 = servletContext.getInitParameter("password");
System.out.println(value1 + ";" + value2);
// 一次性获取Context里所有的初始化参数
Enumeration enumeration = servletContext.getInitParameterNames();
while (enumeration.hasMoreElements()) {
String name = (String) enumeration.nextElement();
String value = servletContext.getInitParameter(name);
System.out.println(name + ";" + value);
}
//获取当前WEB应用的名称
System.out.println(servletContext.getContextPath());
}
...
}
重新整理了下
ends ~