• 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学习相关的电子书资源,如果经济能力允许,还请支持图书作者的纸质正版书籍,创作不易。

  • 相关阅读:
    c++/c语言中如何调用DLL
    fortran出现stack overflow的原因及解决办法
    iOS: ARC和非ARC下使用Block属性的问题
    Objective-C Autorelease Pool 的实现原理
    class-dump 复制到/usr/bin目录不可写,Operation not permitted 解决办法
    Auto Layout 使用心得
    iOS-关于微信支付
    IOS应用安全(五):高级Runtime分析和操作
    Objective-C Runtime 运行时之六:拾遗
    Objective-C Runtime 运行时之五:协议与分类
  • 原文地址:https://www.cnblogs.com/xiaochuan94/p/9143316.html
Copyright © 2020-2023  润新知