编译软件:IntelliJ IDEA 2019.2.4 x64
操作系统:win10 x64 位 家庭版
服务器软件:apache-tomcat-8.5.27
一. 什么是Servlet?
Servlet,英文全称为Server Applet,意为服务器端的一小程序
。它运行在支持Java Servlet规范的Web服务器上。在服务器上部署的众多web应用程序中,无论它是B/S架构,还是C/S架构,它们的基本运行模式如下图所示(以Java程序为例):
如果把上述web应用的运行模式比作是一个正在在营业的餐厅,那Servlet在其中扮演着服务员的角色,客人进店吃饭(客户端发出请求),它负责给客人上菜单,等客人点好菜单,servlet就会通知厨子(web应用)做菜(处理业务),厨子做好菜,就让服务员去上菜(响应)给客人。
总的来说,Servlet就是和客户端进行交互(处理请求和响应)
Servlet通常被用于创建像电子商务网站、社交媒体应用、在线银行网站等类似的Web应用程序。通过使用Servlet,开发人员可以以一种可移植、灵活、高效和可重用的方式构建Web应用程序。
二. 如何编写第一个servlet程序?
步骤:
①创建一个html页面,在上面创建一个超链接(计划访问后台的HelloServlet)
<a href="">访问HelloServlet</a>
②创建HelloServlet
- 新建一个普通类HelloServelet
- HelloServelet实现接口Servlet
- 实现接口中的所有抽象方法
代码演示如下:
import javax.servlet.*; import java.io.IOException; import java.util.Enumeration; public class HelloServelet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } /** * 主要功能:处理客户端的请求和响应 * @param servletRequest 处理请求 * @param servletResponse 处理响应 * @throws ServletException * @throws IOException */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("访问了HelloServlet类的service方法......."); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
- 在web.xml中为HelloServlet设置访问路径
代码演示如下:
<!-- HelloServlet的访问路径:/hello --> <servlet> <!-- 为Servlet起个名字 --> <servlet-name>abc</servlet-name> <!-- Servlet的全类名 --> <servlet-class>t1.HelloServelet</servlet-class> </servlet> <servlet-mapping> <!-- 要和Servlet中的servlet-name的名字一致 --> <servlet-name>abc</servlet-name> <!-- 设置访问路径,注意,必须是/开头 --> <url-pattern>/hello</url-pattern> </servlet-mapping>
③将设置到的访问路径设置给超链接
<a href="hello">访问HelloServlet</a>
④测试HelloServelt
注意:
网页必须直接在web下(不能放在WEB-INF下)
web.xml中url-pattern的值必须以/开头
- 网页的请求路径,不能以/开头
- 网页不能采用静态的打开方式
请求原理如下所示:
Servlet的对象管理:
Servlet的实例对象由Servlet容器(tomcat)负责创建
Servlet的方法由容器在特定情况下调用
Servlet容器会在web应用卸载时(tomcat停止)销毁Servlet对象的实例
三. Servlet的生命周期
Servlet接口中一共有五个方法,其中有三个和生命周期有(init/service/destroy)的方法。
请求过程:
默认情况下在第一次发出请求时,Servlet容器(tomcat服务器)会创建相应的servlet对象、进行初始化(执行init方法)、执行service方法
第二次以及以后的每一次请求发出,都直接执行service方法
在web应用被卸载(服务器被停止时)的时候,servlet对象会被销毁,销毁之前执行destroy方法
Servlet可以在启动服务器时就创建其对象吗?
可以
方法如下:
在web-xml中当前Servlet的servlet标签内添加标签
//设置自启动 <load-on-startup>l</1oad-on-startup>
代码演示如下:
<!-- 设置自启动,若有多个servlet都设了自启动,根据标签体中的值来判定启动优先级,值越小,优先级越高 --> <!-- <load-on-startup></load-on-startup>中的标签体为非0的整数 --> <load-on-startup>1</load-on-startup>
四. Servlet的技术体系
创建Servlet的三种方式:
①实现Servlet接口
重写其五个方法(重点关注的只有一个service),其他四个还必须重写
案例:创建HelloServelet 类实现Servlet 接口
代码演示如下:
import javax.servlet.*; import java.io.IOException; import java.util.Enumeration; public class HelloServelet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } /** * 主要功能:处理客户端的请求和响应 * @param servletRequest 处理请求 * @param servletResponse 处理响应 * @throws ServletException * @throws IOException */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("访问了HelloServlet类的service方法......."); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
web-xml创建其访问路径:
<!-- HelloServlet的访问路径:/hello --> <servlet> <!-- 为Servlet起个名字 --> <servlet-name>abc</servlet-name> <!-- Servlet的全类名 --> <servlet-class>t1.HelloServelet</servlet-class> </servlet> <servlet-mapping> <!-- 要和Servlet中的servlet-name的名字一致 --> <servlet-name>abc</servlet-name> <!-- 设置访问路径,注意,必须是/开头 --> <url-pattern>/hello</url-pattern> </servlet-mapping>
②继承GenericServlet
步骤:
- 创建一个类
- 继承一个抽象类(GenericServlet)
- 实现抽象类中的抽象方法
- 在web-xml中配置Servlet的访问路径
注意:
GenericServlet主要的功能是将service以外的四个方法做了实现。我们自己的Servlet只需要实现service方法即可,如果想用其他的四个方法,可以采用重写。
案例:创建MyFirstServlet类继承GenericServlet类
代码演示如下:
public class MyFirstServlet extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("触发了继承GenericServlet类的子类MyFirstServlet类的service方法......"); } }
web-xm配置其访问路径:
<!-- 设置访问MyFirstServlet的路径:/myfirst --> <servlet> <servlet-name>def</servlet-name> <servlet-class>t1.MyFirstServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>def</servlet-name> <url-pattern>/myfirst</url-pattern> </servlet-mapping>
③继承HttpServlet
步骤:
- 创建一个类
- 继承一个抽象类(HttpServlet)
- 重写两个方法doGet和doPost
- 配置Servlet的访问路径
注意:
HttpServlet主要功能是实现service方法,然后对请求进行分发的操作(不同的请求方式调用不同的方法)。get请求调用doGet方法,post请求调用doPost方法。
案例:创建MyFirstServlet类继承GenericServlet类
代码演示如下:
import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class SecondServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问了SecondServlet里的doPost方法"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问了SecondServlet里的doGet方法"); } }
web-xm配置其访问路径:
<!-- 设置访问SecondServlet的路径:/second --> <servlet> <servlet-name>SecondServlet</servlet-name> <servlet-class>t1.SecondServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SecondServlet</servlet-name> <url-pattern>/second</url-pattern> </servlet-mapping>
五. web项目中的两个接口
5.1 Servletconfig接口
一个Servlet对象对应唯一的一个ServletConfigi配置对象
Servletconfig对象如何获得?
在init方法的形参位置,Servletconfig是在当前Servlet进行初始化的时候,传递给init方法的
主要功能:
- 获取Servlet名称(web.xml中servlet-name的值)
//获取Servlet名称 String servletName = servletConfig.getServletName(); System.out.println("servletName:"+servletName);
- 获取全局上下文(ServletContext)对象
//获取全局上下文对象 ServletContext servletContext = servletConfig.getServletContext(); System.out.println("servletContext:"+servletContext);
- 获取Servlet初始化参数
获取Servlet初始化参数的前提是要有servlet的初始化参数
- 如何设置servlet的初始化参数?
位置:web.xml的servlet标签内,在子标签1–>之上设置,不然报错
代码演示如下:
<!--设置当前Servlet的初始化参数--> <init-param> <param-name>path</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param>
- 获取Servlet初始化参数:
//获取web-xml中的servlet标签内的初始化参数<param-name>为path的value值 String path = servletConfig.getInitParameter("path"); System.out.println("path:"+path); //获取HelloServelet内所有初始化参数的<param-name>【key】值 Enumeration<String> initParameterNames = servletConfig.getInitParameterNames(); while (initParameterNames.hasMoreElements()){ System.out.println("initParameterNames.nextElement():"+initParameterNames.nextElement()); }
案例:在HelloServelet类实现上述功能
代码演示如下:
import javax.servlet.*; import java.io.IOException; import java.util.Enumeration; public class HelloServelet implements Servlet { public HelloServelet() { System.out.println("HelloServelet类的构造方法被执行了"); } @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("HelloServelet类的init方法被执行了"); //1.获取的是当前Servlet名称(web.xml中配置servlet-name的值) String servletName = servletConfig.getServletName(); System.out.println("servletName:"+servletName); //2.获取全局上下文ServletContext对象 ServletContext servletContext = servletConfig.getServletContext(); System.out.println("servletContext:"+servletContext); //3.获取Servlet初始化参数 //获取web-xml中的servlet标签内的初始化参数<param-name>为path的value值 String path = servletConfig.getInitParameter("path"); System.out.println("path:"+path); //获取web-xml中的初始化参数<param-name>为aaa的value值 String aaa = servletConfig.getInitParameter("aaa"); System.out.println("aaa:"+aaa); //获取HelloServelet内所有初始化参数的<param-name>【key】值 Enumeration<String> initParameterNames = servletConfig.getInitParameterNames(); while (initParameterNames.hasMoreElements()){ System.out.println("initParameterNames.nextElement():"+initParameterNames.nextElement()); } } @Override public ServletConfig getServletConfig() { return null; } /** * 主要功能:处理客户端的请求和响应 * @param servletRequest 处理请求 * @param servletResponse 处理响应 * @throws ServletException * @throws IOException */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("访问了HelloServlet类的service方法......."); } @Override public String getServletInfo() { return null; } @Override public void destroy() { System.out.println("HelloServelet类的destroy方法被执行了"); } }