Servlet(二):初识Servlet

在手动写完一个Servlet小例子后,是不是有很多疑问,接下来会为大家详细介绍Servlet的知识。

1、什么是Servlet

是在服务器上运行的小程序。一个servlet就是一个Java类,并且可以通过“请求-响应”编程模型来访问驻留在服务器内存里的servlet程序。

2、为什么要用Servlet

web服务器只能处理静态资源的请求,需要事先将静态页面写好,不能处理动态资源请求(动态资源请求主要是一些需要计算或数据操作而生产的页面),在早期为了解决这一问题,使用了CGI程序(Common Gateway Interface通用网关接口)来扩展web服务器的功能,但是其性能较差,可移植性差,慢慢被弃用。

Servlet的出现很好的解决使用CGI出现的问题。第一,Servlet可移植性强,Servlet是用Java语言实现的,具备一处编写处处运行的特点。第二,Servlet可扩展性强,可使用Java的所有类库,并且可以通过sockets和RMI机制(Remote Method Invocation远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法,这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。)与数据库或其他软件进行交互。第三,Servlet性能更好,Servlet只需web服务器加载一次,而且可以在不同请求之间保持服务;相反,每一次对CGI脚本的请求,都会使Web服务器加载并执行该脚本。一旦这个CGI脚本运行结束,它就会被从内存中清除,然后将结果返回到客户端。CGI脚本的每一次使用都会造成程序初始化过程的重复执行。

3、编写Servlet的步骤

A.编写一个Java类,继承HttpServlet,重写doGet()方法和doPost()方法。

B.配置web.xml文件。

C.编写jsp页面。

D.启动容器,访问servlet,在浏览器验证。

4、Servlet的执行流程

5、Servlet的生命周期

Servlet的生命周期是指Servlet容器如何创建Servlet对象,如何对其进行初始化,如何调用Servlet对象处理请求,如何销毁Servlet对象的整个过程。

主要分为四个阶段:(1)实例化;(2)初始化;(3)调用;(4)销毁。

A.实例化阶段。Servlet实例会在以下两种情况下创建:一是在Servlet容器收到request请求后创建;二是在Servlet容器启动时创建,需要在web.xml中配置<load-on-startup>1</load-on-startup>标签,中间的值是一个大于0的整数,值越小优先级越高。

B.初始化阶段。Servlet实例化后,会调用init(ServletConfig config)方法,其中ServletConfig对象是一个成员变量,是Servlet容器传递进来的,init方法只会执行一次。

C.调用阶段。servlet容器收到请求后,调用servlet对象的service()方法,再将处理结果返回给浏览器。

D.销毁阶段。对server执行stop操作或将服务关闭时,调用servlet对象的destroy方法,且只会执行一次。

6、实操验证

新建一个Maven web项目,写好servlet,配置好web.xml,写一个简单的jsp页面,可以来实际验证刚才的分析。

A.新建两个Java类,继承HttpServlet

/**
 * servlet的生命周期
 * @author 小川94
 * @date 2018年6月4日
 */
public class LifeServlet extends HttpServlet {
    
    private static final long serialVersionUID = 1L;
       
    
    public LifeServlet() {
        System.out.println("LifeServlet:执行构造方法...");
    }
    
    @Override
    public void init() throws ServletException {
        System.out.println("LifeServlet:执行init方法...");
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 打印日志
        System.out.println("LifeServlet:处理Get请求...");
        // 设置服务器返回的数据类型
        response.setContentType("text/html");
        // 获取一个输出流
        PrintWriter out = response.getWriter();
        // 输出数据,将数据发送到浏览器
        out.println("<h1>Hello Servlet!</h1>");
        // 关闭流
        out.close();
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 打印日志
        System.out.println("LifeServlet:处理Post请求...");
        // 对从浏览器获取的数据设置编码格式
        request.setCharacterEncoding("UTF-8");
        // 获取页面传入的数据
        String name = request.getParameter("name");
        System.out.println(name);
        // 设置服务器返回的数据类型
        response.setContentType("text/html;charset=UTF-8");
        // 获取一个输出流
        PrintWriter out = response.getWriter();
        // 输出数据,将数据发送到浏览器
        out.println("<h1>Hello "+name+"!</h1>");
        // 关闭流
        out.close();
    }

    @Override
    public void destroy() {
        System.out.println("LifeServlet:执行destroy方法...");
    }

}
public class LifeServlet2 extends HttpServlet {
    
    private static final long serialVersionUID = 1L;
       
    
    public LifeServlet2() {
        System.out.println("LifeServlet2:执行构造方法...");
    }
    
    @Override
    public void init() throws ServletException {
        System.out.println("LifeServlet2:执行init方法...");
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 打印日志
        System.out.println("LifeServlet2:处理Get请求...");
        // 设置服务器返回的数据类型
        response.setContentType("text/html");
        // 获取一个输出流
        PrintWriter out = response.getWriter();
        // 输出数据,将数据发送到浏览器
        out.println("<h1>Hello Servlet!</h1>");
        // 关闭流
        out.close();
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 打印日志
        System.out.println("LifeServlet2:处理Post请求...");
        // 对从浏览器获取的数据设置编码格式
        request.setCharacterEncoding("UTF-8");
        // 获取页面传入的数据
        String name = request.getParameter("name");
        System.out.println(name);
        // 设置服务器返回的数据类型
        response.setContentType("text/html;charset=UTF-8");
        // 获取一个输出流
        PrintWriter out = response.getWriter();
        // 输出数据,将数据发送到浏览器
        out.println("<h1>Hello "+name+"!</h1>");
        // 关闭流
        out.close();
    }

    @Override
    public void destroy() {
        System.out.println("LifeServlet2:执行destroy方法...");
    }
}

B.配置web.xml文件

<servlet>
    <servlet-name>LifeServlet2</servlet-name>
    <servlet-class>servlet.LifeServlet2</servlet-class>
    <!-- 设置装载优先级 -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>LifeServlet2</servlet-name>
    <url-pattern>/LifeServlet2</url-pattern>
  </servlet-mapping>
  
  <servlet>
    <servlet-name>LifeServlet</servlet-name>
    <servlet-class>servlet.LifeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LifeServlet</servlet-name>
    <url-pattern>/LifeServlet</url-pattern>
  </servlet-mapping>

C.编写jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>第一个servlet例子</title>
</head>
<body style="margin:50px;">

<!-- 演示get请求 -->
<a href="LifeServlet">Get请求</a>

<!-- 演示post请求 -->
<form action="LifeServlet" method="post">
    <label>姓名</label>
    <input type="text" name="name"/>
    <br/>
    <input type="submit" value="提交"/>
</form>

<br/>
<br/>

<!-- 演示get请求 -->
<a href="LifeServlet2">Get请求</a>

<!-- 演示post请求 -->
<form action="LifeServlet2" method="post">
    <label>姓名</label>
    <input type="text" name="name"/>
    <br/>
    <input type="submit" value="提交"/>
</form>


</body>
</html>

我们进行了两次实验,一次是没有在web.xml文件里添加<load-on-startup>1</load-on-startup>,处理页面请求时,是调用哪个servlet才会去装载哪个servlet,然后进行一系列的操作。

第二次是为LifeServlet2添加了<load-on-startup>1</load-on-startup>标签,在Tomcat启动的时候,Servlet容器就装载了LifeServlet2并初始化,然后根据浏览器的请求来执行对应的方法,最后再销毁。

 

文章首发于我的个人公众号:悦乐书。喜欢分享一路上听过的歌,看过的电影,读过的书,敲过的代码,深夜的沉思。期待你的关注!

公众号后台输入关键字“Java学习电子书”,即可获得12本Java学习相关的电子书资源,如果经济能力允许,还请支持图书作者的纸质正版书籍,创作不易。

posted @ 2018-06-06 09:18  程序员小川  阅读(426)  评论(0编辑  收藏  举报