servlet入门_servlet快速入门 - CSDN
精华内容
参与话题
  • javaweb—servlet的简单入门使用

    万次阅读 2016-07-22 11:00:50
    Servlet(Server Applet),全称JavaServlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指...

    ServletServer Applet),全称JavaServlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

    Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。[百度百科]

     

    ** 如何使用servlet?

    #1.编写一个继承与HttpServletjava

    #2.重写doGetdoPost方法

    #3.配置web.xml文件,配置servlet节点

    MyFirstServlet.java

    package com.ibatis01.servlet;

     

    import java.io.IOException;

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    public class MyFirstServlet extends HttpServlet {

     

             protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                       response.getWriter().append("my frist servlet");

             }

     

             protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                       doGet(request, response);

             }

    }

    Web.xml

    ……

    <servlet>

        <servlet-name>MyFirstServlet</servlet-name>

        <servlet-class>com.ibatis01.servlet.MyFirstServlet</servlet-class>

      </servlet>

      <servlet-mapping>

        <servlet-name>MyFirstServlet</servlet-name>

        <url-pattern>/MyFirst</url-pattern>

      </servlet-mapping>

    ……

    运行结果:

    ** URL匹配

                        url-pattern                   浏览器输入

    精确匹配             /first                 http://localhost:8080/day/first

                                                   /itcast/demo1          http://localhost:8080/day/itcast/demo1

     

    模糊匹配             /*                   http://localhost:8080/day/任意路径

                                                   /itcast/*               http://localhost:8080/day/itcast/任意路径

                                                  *.后缀名              http://localhost:8080/day/任意路径.do

                                                   *.do

                                                   *.action

                                                   *.html(伪静态):并不是一个真的静态文件

    默认路径[缺省路径,尽量少用]       /          http://localhost:8080/day

    注意:

    #1.路径要不就是/开始,要不就是*开始,而且两种不能混合在一起用。

    #2.当多个servlet被同时匹配,精确匹配优先

    #3.默认路径:当路径匹配不到任何自定义的servleturl路径,则去tomcat下找DefaultServlet到对象的应用下查找对应的静态文件,如果还找不到就返回404 not found[先找动态资源,再找静态文件]

     

    ** servlet的生命周期

    构造方法:第一次访问servlet时候调用

    init方法:创建完servlet时候调用

             service方法:每次请求的时候调用

             destroy方法:当servlet被销毁时候被调用

    注意:

    #1. service方法本来是用来分发调用doPost方法还是doGet方法,如果我们重写了service方法就不会调用doGet或者doPost方法。

    #2. Init 方法有有参数和无参数两种方法,有参数的其实还是会调用无参的,所以servlet方法初始化代码写在无参数的init方法即可

    #3. Servlet对象在tomcat中是单实例多线程的[servlet肯定用了多线程]

    package com.ibatis01.servlet;

     

    import java.io.IOException;

     

    import javax.servlet.ServletConfig;

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    publicclass MyFirstServlet extends HttpServlet {

       

        /**

         * 构造方法

        */

        public MyFirstServlet() {

           System.out.println("1. 我被创建了......");

        }

       

        /**

         * init方法

        */

        @Override

        public void init(ServletConfig config) throws ServletException {

           System.out.println("2. init方法被调用......");

        }

       

        /**

         * service方法

         */

        @Override

        protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {

           System.out.println("3. service方法被调用......");

        }

       

        @Override

        public void destroy() {

           System.out.println("4. 调用destroy方法......");

        }

       

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

           System.out.println("doGet 方法被调用......");

           response.getWriter().append("my frist servlet");

        }

     

        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

           System.out.println("doPost 方法被调用......");

           doGet(request, response);

        }

    }

     

     

    ** servlet的自动加载

    web.xml中加入load-on-startup即可[中间的数值越大优先级越低]

    <servlet>

        <servlet-name>MyFirstServlet</servlet-name>

        <servlet-class>com.ibatis01.servlet.MyFirstServlet</servlet-class>

        <!-- servlet在服务器启动的时候就创建 -->

        <load-on-startup>1</load-on-startup>

      </servlet>

     

    ** servlet的线程安全问题

    由于servlet是单实例多线程的,所以有可能引发多线程问题!

    package com.ibatis01.servlet;

     

    import java.io.IOException;

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    public class ThreadServlet extends HttpServlet {

          

             private int num=0;

     

             protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                       try {

                                num++;

                                Thread.sleep(2000);

                                response.getWriter().append(this.toString()+"<br/>").append("num="+num);

                       } catch (InterruptedException e) {

                                e.printStackTrace();

                       }       

             }

     

             protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                       doGet(request, response);

             }

    }

    结果是:[出现了想要的问题]

    可以通过加锁来来解决问题

    package com.ibatis01.servlet;

     

    import java.io.IOException;

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    public class ThreadServlet extends HttpServlet {

     

             private int num = 0;

     

             protected void doGet(HttpServletRequest request, HttpServletResponse response)

                                throws ServletException, IOException {

                       synchronized (this) {

     

                                try {

                                         num++;

                                         Thread.sleep(2000);

                                         response.getWriter().append(this.toString() + "<br/>").append("num=" + num);

                                } catch (InterruptedException e) {

                                         e.printStackTrace();

                                }

                       }

             }

     

             protected void doPost(HttpServletRequest request, HttpServletResponse response)

                                throws ServletException, IOException {

                       doGet(request, response);

             }

    }

     

    展开全文
  • Servlet 入门

    千次阅读 2019-08-28 23:23:23
    二、Servlet 入门 1、创建JavaEE Web项目 2、定义类,实现 Servlet 接口 3、实现接口中的抽象方法 4、配置 Servlet 三、Servlet 分析 1、原理分析 2、Servlet 中的生命周期 四、注解配置(不用web.xml配置)...

    目录

    一、Servlet 介绍

    二、Servlet 入门

    1、创建JavaEE Web项目

    2、定义类,实现 Servlet 接口

    3、实现接口中的抽象方法

    4、配置 Servlet

    三、Servlet 分析

    1、原理分析

    2、Servlet 中的生命周期

    四、注解配置(不用web.xml配置)

    五、Servlet 体系结构

    1、GenericServlet 类

    2、HttpServlet 类


    一、Servlet 介绍

    Servlet(server applet)是运行在服务器端的小程序,其实就是一个接口,定义了 Java 类被浏览器访问到(Tomcat 识别)的规则,我们可以自己定义一个类,来实现 Servlet 接口,复写方法

    二、Servlet 入门

    1、创建JavaEE Web项目

    具体参见上一篇博客

    2、定义类,实现 Servlet 接口

    public class myServlet implements Servle{}

    3、实现接口中的抽象方法

    public class myServlet implements Servlet {
        /**
         * 初始化方法
         * 在Servlet被创建是执行,只会执行一次
         */
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("初始化");
        }
    
        /**
         * 获取ServletConfig配置对象
         * @return
         */
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        /**
         * 提供服务的方法
         * 每次Servlet被访问的时候执行,可执行多次
         * @return
         */
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("Hello Servlet!");
        }
    
        /**
         * 获取Servlet信息,如作者、版本等
         * @return
         */
        @Override
        public String getServletInfo() {
            return null;
        }
    
        /**
         * 销毁方法
         * 在服务器正常关闭的时候执行,执行一次
         */
        @Override
        public void destroy() {
            System.out.println("销毁");
        }
    }

    4、配置 Servlet

    在 web.xml 文件里面进行配置,在根标签里面加入如下配置

    <!--配置Servlet -->
    <servlet>
        <servlet-name>oneStar</servlet-name>
        <servlet-class>web.servlet.myServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>oneStar</servlet-name>
        <url-pattern>/oneStar</url-pattern>
    </servlet-mapping>

    三、Servlet 分析

    1、原理分析

    1. 当服务器接收到客户端浏览器的请求后,会解析请求的URL路径,获取访问的 Servlet 的资源路径
    2. 查找 web.xml 文件,看是否有对应的<url-pattern>标签体内容
    3. 如果有,则再找到对应的<url-pattern>全类名
    4. Tomcat 将字节码文件加载进内存,并创建其对象
    5. 调用其方法

    2、Servlet 中的生命周期

    • 被创建:执行 init 方法,只执行一次
      • 默认情况下,第一次被访问时,Servlet 被创建
      • 可以配置执行 Servlet 的创建时机,可在<servlet>标签中配置
        1. 配置第一次被访问时创建:<load-on-startup>标签配置为负数(默认为-1)
        2. 配置服务器启动时被创建:<load-on-startup>标签配置0或正数
      • init 方法只执行一次,说明一个 Servlet 在内存中只存在一个对象,Servlet 是单例的
        • 多个用户同时访问时,可能存在线程安全问题,所以尽量不要在Servlet中定义成员变量,即使定义了也不要对值进行修改
    • 提供服务:执行 server 方法,可以执行多次
      • 每次访问 Servlet 时,Servlet 方法都会被调用一次
    • 被销毁:执行 destory 方法,只执行一次
      • Servlet 销毁时执行,只有服务器正常关闭时,才会执行 destory 方法

    四、注解配置(不用web.xml配置)

    在 Servlet3.0 以上的版本中,支持使用注解配置,可以不需要 web.xml 文件,在类上使用 @webServlet 注解进行配置,其实质就是配置WebServlet.class 文件里面的 urlPatterns 参数,urlPatterns 是一个 String 类型的数组,使用该数组来配置访问路径,该配置有多种方法:

    • 一个 Servlet 可以定义一个访问路径:@WebServlet("/oneStar")
    • 一个 Servlet 可以定义一个数组(多个)访问路径:@WebServlet({"/oneStar","/twoStar","/threeStar"})
    • 支持多层路径:@WebServlet("/user/oneStar")
    • 使用通配(任何目录):@WebServlet("/*")
    • 使用通配(带后缀):@WebServlet("*.do")
    @WebServlet("/oneStar")
    //@WebServlet({"/oneStar","/twoStar","/threeStar"})
    //@WebServlet("/user/oneStar")
    //@WebServlet("/*")
    //@WebServlet("*.do")
    public class Main implements Servlet {}

    这样就可以启动项目了

    五、Servlet 体系结构

    Servlet 是一个接口,定义了 Java 类被浏览器访问到的很多方法,我们可以直接去实现这些方法,但一般不这样做,而是使用 Servlet 接口的抽象子类 GenericServlet 类或者 GenericServlet 的抽象子类 HttpServlet 类,实现 service() 方法。

    1、GenericServlet 类

    将 Servlet 接口中其他的方法做了默认空实现,只将 service() 方法作为抽象,因此可以直接继承 GenericServlet,实现 service() 方法即可,而在实际开发当中,往往会在 service() 方法中判断请求的方式,判断是 get 方法还是 post 方法,是一个比较繁琐的过程,因此可以使用 HttpServlet 类来简化了这一过程。

    2、HttpServlet 类

    HttpServlet 类是对 HTTP 协议的封装,简化了操作

    • 定义类继承 HttpServlet
    • 重写 doGet 或 doPost 方法
    @WebServlet("/oneStar")
    public class Main extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("Do Get!");
        }
    }

     

    展开全文
  • Servlet入门

    2020-03-21 22:52:05
    Servlet 是 Server Applet 的简称,译为“服务器端小程序”。Servlet 是 Java 的一套技术标准,规定了如何使用 Java 来开发动态网站。换句话说,Java 可以用来开发网站后台,但是要提前定义好一套规范,并编写基础...

    Servlet 是 Server Applet 的简称,译为“服务器端小程序”。Servlet 是 Java 的一套技术标准,规定了如何使用 Java 来开发动态网站。换句话说,Java 可以用来开发网站后台,但是要提前定义好一套规范,并编写基础类库,这就是 Servlet 所做的事情。

    Java Servlet 可以使用所有的 Java API,Java 能做的事情,Servlet 都能做。

    Servlet 只是古老的 CGI 技术的替代品,直接使用 Servlet 开发还是很麻烦,所以 Java 后来又对 Servlet 进行了升级,推出了 JSP 技术。JSP 只是对 Servlet 加了一层壳,JSP 经过编译后还是 Servlet。

    Java Servlet是什么?它有哪些特点?

    Servlet(Server Applet)是 Java Servlet 的简称,是使用 Java 语言编写的运行在服务器端的程序。具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

    通常来说,Servlet 是指所有实现了 Servlet 接口的类。

    Servlet 主要用于处理客户端传来的 HTTP 请求,并返回一个响应,它能够处理的请求有 doGet() 和 doPost() 等。

    Servlet 由 Servlet 容器提供,Servlet 容器是指提供了 Servlet 功能的服务器(如 Tomcat)。

    Servlet 容器会将 Servlet 动态加载到服务器上,然后通过 HTTP 请求和 HTTP 应与客户端进行交互。
    Servlet 应用程序的体系结构如图 1 所示。
    在这里插入图片描述
    在图 1 中,Servlet 的请求首先会被 HTTP 服务器(如 Apache)接收,HTTP 服务器只负责静态 HTML 页面的解析,而 Servlet 的请求会转交给 Servlet 容器,Servlet 容器会根据 web.xml 文件中的映射关系,调用相应的 Servlet,Servlet 再将处理的结果返回给 Servlet 容器,并通过 HTTP 服务器将响应传输给客户端。

    Servlet 技术具有如下特点。
    1)方便
    Servlet 提供了大量的实用工具例程,如处理很难完成的 HTML 表单数据、读取和设置 HTTP 头,以及处理 Cookie 和跟踪会话等。
    2)跨平台
    Servlet 使用 Java 类编写,可以在不同的操作系统平台和不同的应用服务器平台运行。
    3)灵活性和可扩展性强
    采用 Servlet 开发的 Web 应用程序,由于 Java 类的继承性及构造函数等特点,使得应用灵活,可随意扩展。

    除了上述几点以外,Servlet 还具有功能强大、能够在各个程序之间共享数据、安全性强等特点.

    与Servlet相关的接口和类

    Sun 公司提供了一系列的接口和类用于 Servlet 技术的开发,其中最重要的接口是 javax.servlet.Servlet。在 Servlet 接口中定义了 5 个抽象方法,如表 1 所示。
    在这里插入图片描述
    在表 1 中,列举了 Servlet 接口中的五个方法,其中 init()、service() 和 destroy() 方法可以表现 Servlet 的生命周期,它们会在某个特定的时刻被调用。

    针对 Servlet 的接口,Sun 公司提供了两个默认的接口实现类:GenericServlet 和 HttpServlet。其中,GenericServlet 是一个抽象类,该类为 Servlet 接口提供了部分实现,它并没有实现 HTTP 请求处理。

    HttpServlet 是 GenericServlet 的子类,它继承了 GenericServlet 的所有方法,并且为 HTTP 请求中的 GET 和 POST 等类型提供了具体的操作方法。通常情况下,编写的 Servlet 类都继承自 HttpServlet,在开发中使用的也是 HttpServlet 对象。

    HttpServlet 类中包含两个常用方法,这两个方法的说明如表 2 所示。
    在这里插入图片描述
    HttpServlet 主要有两大功能,具体如下。
    1.根据用户请求方式的不同,定义相应的 doXxx() 方法处理用户请求。例如,与 GET 请求方式对应的 doGet() 方法,与 POST 方式对应的 doPost() 方法。
    2.通过 service() 方法将 HTTP 请求和响应分别强转为 HttpServletRequest 和 HttpServletResponse 类型的对象。

    需要注意的是,由于 HttpServlet 类在重写的 service() 方法中,为每一种 HTTP 请求方式都定义了对应的 doXxx() 方法,因此,当定义的类继承 HttpServlet 后,只需要根据请求方式重写对应的 doXxx() 方法即可,而不需要重写 service() 方法。

    第一个Servlet程序

    http://c.biancheng.net/view/3985.html

    Servlet生命周期详解

    在这里插入图片描述
    图 1 描述了 Servlet 的生命周期。按照功能的不同,大致可以将 Servlet 的生命周期分为三个阶段,分别是初始化阶段、运行阶段和销毁阶段。
    1)初始化阶段
    当客户端向 Servlet 容器发出 HTTP 请求要求访问 Servlet 时,Servlet 容器首先会解析请求,检查内存中是否已经有了该 Servlet 对象,如果有,则直接使用该 Servlet 对象,如果没有,则创建 Servlet 实例对象,然后通过调用 init() 方法实现 Servlet 的初始化工作。需要注意的是,在 Servlet 的整个生命周期内,它的 init() 方法只能被调用一次。
    2)运行阶段
    这是 Servlet 生命周期中最重要的阶段,在这个阶段中,Servlet 容器会为这个请求创建代表 HTTP 请求的 ServletRequest 对象和代表 HTTP 响应的 ServletResponse 对象,然后将它们作为参数传递给 Servlet 的 service() 方法。

    service() 方法从 ServletRequest 对象中获得客户请求信息并处理该请求,通过 ServletResponse 对象生成响应结果。

    在 Servlet 的整个生命周期内,对于 Servlet 的每一次访问请求,Servlet 容器都会调用一次 Servlet 的 service() 方法,并且创建新的 ServletRequest 和 ServletResponse 对象,也就是说,service() 方法在 Servlet 的整个生命周期中会被调用多次。
    3)销毁阶段
    当服务器关闭或 Web 应用被移除出容器时,Servlet 随着 Web 应用的关闭而销毁。在销毁 Servlet 之前,Servlet 容器会调用 Servlet 的 destroy() 方法,以便让 Servlet 对象释放它所占用的资源。在 Servlet 的整个生命周期中,destroy() 方法也只能被调用一次。

    需要注意的是,Servlet 对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭或 Web 应用被移除出容器时,Servlet 对象才会销毁。

    Servlet配置虚拟路径映射

    在 web.xml 文件中,一个 元素用于映射一个 Servlet 的对外访问路径,该路径也称为虚拟路径。例如,在《第一个Servlet程序》教程中,TestServlet01 所映射的虚拟路径为“/TestServlet01”。

    <servlet-mapping>
        <!-- 映射为Test01 -->
        <servlet-name>TestServlet01</servlet-name>
        <url-pattern>/TestServlet01</url-pattern>
    </servlet-mapping>
    

    创建好的 Servlet 只有映射成虚拟路径,客户端才能对其进行访问。但是在映射 Servlet 时,还有内容需要学习,如 Servlet 的多重映射、在映射路径中使用通配符、配置默认的 Servlet 等。

    Servlet的多重映射

    Servlet 的多重映射指同一个 Servlet 可以被映射成多条虚拟路径。也就是说,客户端可以通过多条路径实现对同一个 Servlet 的访问。Servlet 多重映射的实现方式有以下两种。
    1)配置多个 < servlet-mapping> 元素
    以《第一个Servlet程序》教程中的 TestServlet01 为例,在 web.xml 文件中的 < servlet-mapping> 元素下,增加一个 < servlet-mapping> 元素配置,其增加后的代码如下所示:

    <servlet-mapping>
        <!-- 映射为Test01 -->
        <servlet-name>TestServlet01</servlet-name>
        <url-pattern>/Test01</url-pattern>
    </servlet-mapping>
    

    2)配置多个 < url-pattern> 子元素
    同样以 TestServlet01 为例,在 web.xml 文件中对 TestServlet01 的 < servlet-mapping> 元素进行修改,在该元素中配置多个 < url-pattern>,修改后的代码如下所示:

    <servlet-mapping>
        <!-- 映射为TestServlet01和Test02 -->
        <servlet-name>TestServlet01</servlet-name>
        <url-pattern>/TestServlet01</url-pattern>
        <url-pattern>/Test02</url-pattern>
    </servlet-mapping>
    

    Servlet映射路径中使用通配符

    在实际开发过程中,开发者有时会希望某个目录下的所有路径都可以访问同一个 Servlet,这时,可以在 Servlet 映射的路径中使用通配符*。通配符的格式有两种,具体如下。

    • 格式为“*.扩展名”,例如 *.do 匹配以 .do 结尾的所有 URL 地址。
    • 格式为 /,例如 /abc/ 匹配以 /abc 开始的所有 URL 地址。

    需要注意的是,这两种通配符的格式不能混合使用,例如,/abc/*.do 是不合法的映射路径。另外,当客户端访问一个 Servlet 时,如果请求的 URL 地址能够匹配多条虚拟路径,那么 Tomcat 将采取最具体匹配原则查找与请求 URL 最接近的虚拟映射路径。例如,对于如下所示的一些映射关系:

    /abc/*  映射到 Servlet1
    /*         映射到 Servlet2
    /abc     映射到 Servlet3
    *.do     映射到 Servlet4
    
    • 当请求 URL 为 /abc/a.html,/abc/* 和 /* 都可以匹配这个 URL,Tomcat 会调用 Servlet1。
    • 当请求 URL 为 /abc、/、/abc/ 和 /abc 都可以匹配这个 URL,Tomcat 会调用 Servlet3。
    • 当请求 URL 为 /abc/a.do、/.do 和 /abc/* 都可以匹配这个 URL,Tomcat 会调用 Servlet1。
    • 当请求 URL 为 /a.do,/* 和 *.do 都可以匹配这个 URL,Tomcat 会调用 Servlet2。
    • 当请求 URL 为 /xxx/yyy/a.do,.do 和 / 都可以匹配这个 URL,Tomcat 会调用 Servlet2。

    默认Servlet

    如果某个 Servlet 的映射路径仅仅是一个正斜线(/),那么这个 Servlet 就是当前 Web 应用的默认 Servlet。Servlet 服务器在接收到访问请求时,如果在 web.xml 文件中找不到匹配的 < servlet-mapping> 元素的 URL,则会将访问请求交给默认 Servlet 处理,也就是说,默认 Servlet 用于处理其他 Servlet 都不处理的访问请求。

    下面对《第一个Servlet程序》教程中的web.xml文件进行修改,将其设置为默认的 Servlet,具体如下:

    <servlet>
        <servlet-name>TestServlet01</servlet-name>
        <servlet-class>com.mengma.servlet.TestServlet01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet01</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    需要注意的是,在 Tomcat 安装目录下的 web.xml 文件中也配置了一个默认的 Servlet,配置信息如下所示:

    <servlet>
        <servlet-name>default</servlet-name>
        <serlet-class>org.apache.catalina.servlets.DefaultServlet</serlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    在上面的配置信息中,org.apache.catalina.servlets.DefaultServlet 被设置为默认的 Servlet,它对 Tomcat 服务器上所有的 Web 应用都起作用。

    当 Tomcat 服务器中的某个 Web 应用没有默认 Servlet 时,都会将 DefaultServlet 作为默认的 Servlet。当客户端访问 Tomcat 服务器中的某个静态 HTML 文件时,DefaultServlet 会判断 HTML 是否存在,如果存在,则会将数据以流的形式回送给客户端,否则会报告 404 错误。

    ServletConfig接口

    在运行 Servlet 程序时,可能需要一些辅助信息,例如,文件使用的编码、使用 Servlet 程序的共享信息等,这些信息可以在 web.xml 文件中使用一个或多个 < init-param> 元素进行配置。当 Tomcat 初始化一个 Servlet 时,会将该 Servlet 的配置信息封装到 ServletConfig 对象中,此时可以通过调用 init(ServletConfig config)方法将 ServletConfig 对象传递给 Servlet。

    ServletConfig 接口中定义了一系列获取配置信息的方法,如表 1 所示。
    在这里插入图片描述
    1)创建Servlet
    在 com.mengma.servlet 包中创建一个名称为 TestServlet02 的 Servlet 类,并在类中编写用于读取 web.xml 文件中参数信息的代码,如下所示。

    package com.mengma.servlet;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class TestServlet02 extends HttpServlet {
        protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
            PrintWriter out = response.getWriter();
            ServletConfig config = this.getServletConfig();
            String param = config.getInitParameter("encoding");
            out.println("encoding=" + param);
        }
        protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

    2)配置参数信息
    在 web.xml 文件中为 Servlet 配置一些参数信息,具体的配置代码如下所示:

    <servlet>
      <servlet-name>TestServlet02</servlet-name>
      <servlet-class>com.mengma.servlet.TestServlet02</servlet-class>
      <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
      </init-param>
    </servlet>
    <servlet-mapping>
      <servlet-name>TestServlet02</servlet-name>
      <url-pattern>/TestServlet02</url-pattern>
    </servlet-mapping>
    

    在上面的参数信息中,< init-param> 节点表示要设置的参数,该节点中的 < param-name> 表示参数的名称,< param-value> 表示参数的值,在 < init-param> 节点中为 TestServlet02 配置了一个名为 encoding 的参数,并设置其参数的值为 UTF-8。
    3)运行项目并查看结果
    启动 Tomcat 服务器,在浏览器的地址栏中输入地址 http://localhost:8080/servletDemo01/TestServlet02 访问 TestServlet02,结果如图 1 所示。
    在这里插入图片描述

    ServletContext接口

    当 Tomcat 启动时,Tomcat 会为每个 Web 应用创建一个唯一的 ServletContext 对象代表当前的 Web 应用,该对象封装了当前 Web 应用的所有信息。可以利用该对象获取 Web 应用程序的初始化信息、读取资源文件等。下面对 ServletContext 接口的不同作用分别进行讲解。

    1. 获取 Web 应用程序的初始化参数

    在 web.xml 文件中,不仅可以配置 Servlet 的映射信息,还可以配置整个 Web 应用的初始化信息。Web 应用初始化参数的配置方式具体如下所示:

    <context-param>
        <param-name>XXX</param-name>
        <param-value>xxx</param-value>
    </context-param>
    <context-param>
        <param-name>AAA</param-name>
        <param-value>aaa</param-value>
    </context-param>
    
    

    在上面的示例中,<
    context-param> 元素位于根元素 < web-app> 中,它的子元素 < param-name> 和 < param-value> 分别用于指定参数的名字和参数值。要想获取这些参数名和参数值的信息,可以使用 ServletContext 接口中定义的 getInitParameterNames() 和 getInitParameter(String name)方法分别获取。

    下面通过案例演示如何使用 ServletContext 接口获取 Web 应用程序的初始化参数。

    1)在 servletDemo01 项目的 web.xml 文件中配置初始化参数信息和 Servlet 信息,其代码如下所示:

    <context-param>
        <param-name>username</param-name>
        <param-value>admin</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>1234</param-value>
    </context-param>
    <servlet>
        <servlet-name>TestServlet03</servlet-name>
        <servlet-class>com.mengma.servlet.TestServlet03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet03</servlet-name>
        <url-pattern>/TestServlet03</url-pattern>
    </servlet-mapping>
    

    2)在项目的 com.mengma.servlet 包中创建一个名称为 TestServlet03 的类,该类中使用 ServletContext 接口获取 web.xml 中的配置信息,如下所示。

    package com.mengma.servlet;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class TestServlet03 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            // 得到ServletContext对象
            ServletContext context = this.getServletContext();
            // 得到包含所有初始化参数名的Enumeration对象
            Enumeration<String> paramNames = context.getInitParameterNames();
            // 遍历所有的初始化参数名,得到相应的参数值并打印
            while (paramNames.hasMoreElements()) {
              String name = paramNames.nextElement();
              String value = context.getInitParameter(name);
              out.println(name + ":" + value);
              out.println("<br/>");
        }
    }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

    上述代码中,当通过 this.getServletContext() 方法获取到 ServletContext 对象后,首先调用 getInitParameterNames() 方法,获取到包含所有初始化参数名的 Enumeration 对象,然后遍历 Enumeration 对象,根据获取到的参数名,通过 getInitParamter(String name)方法得到对应的参数值。

    2. 读取 Web 应用下的资源文件

    在实际开发中,有时会需要读取 Web 应用中的一些资源文件,如配置文件和日志文件等。为此,在 ServletContext 接口中定义了一些读取 Web 资源的方法,这些方法是依靠 Servlet 容器实现的。Servlet 容器根据资源文件相对于 Web 应用的路径,返回关联资源文件的 I/O 流或资源文件在系统的绝对路径等。

    表 2 中列举了 ServletContext 接口中用于获取资源路径的相关方法。
    在这里插入图片描述
    案例分步骤演示如何使用 ServletContext 对象读取资源文件。

    1)在 servletDemo01 项目的 src 目录中创建一个名称为 itcast.properties 的文件,在创建好的文件中输入如下所示的配置信息:

    username=admin
    password=1234
    

    2)在 com.mengma.servlet 包中创建一个名称为 TestServlet04 的 Servlet 类,使用该类读取 itcast.properties 资源文件的内容,其实现代码如下所示。

    package com.mengma.servlet;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.util.Properties;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class TestServlet04 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            ServletContext context = this.getServletContext();
            PrintWriter out = response.getWriter();
            // 获取相对路径中的输入流对象
            InputStream in = context
                .getResourceAsStream("/WEB-INF/classes/itcast.properties");
            Properties pros = new Properties();
            pros.load(in);
            out.println("username=" + pros.getProperty("username") + "<br/>");
            out.println("password=" + pros.getProperty("password") + "<br/>");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

    在上述代码中,使用 ServletContext 的 getResourceAsStream(String path)方法获得了关联 itcast.properties 资源文件的输入流对象,其中的 path 参数必须以正斜线(/)开始,表示 itcast.properties 文件相对于 Web 应用的相对路径。
    3)启动 Tomcat 服务器,在浏览器的地址栏中输入地址 http://localhost:8080/servletDemo01/TestServlet04 访问 TestServlet04,浏览器的显示结果如图 3 所示。

    运行结果图 3  运行结果

    从图 3 中可以看出,itcast.properties 资源文件中的内容已经被读取了出来。由此可见,使用 ServletContext 可以读取 Web 应用中的资源文件。

    servlet处理用户请求的完整流程

    针对 Servlet 的每次请求,Web 服务器在调用 service() 方法之前,都会创建 HttpServletRequest 和 HttpServletResponse 对象。其中,HttpServletRequest 对象用于封装 HTTP 请求消息,简称 request 对象。HttpServletResponse 对象用于封装 HTTP 响应消息,简称 response 对象。浏览器访问 Servlet 的交互过程如图 1 所示。
    在这里插入图片描述
    在图 1 中,首先浏览器向 Web 服务器发送了一个 HTTP 请求,Web 服务器根据收到的请求,会先创建一个 HttpServletRequest 和 HttpServletResponse 对象,然后再调用相应的 Servlet 程序。

    在 Servlet 程序运行时,它首先会从 HttpServletRequest 对象中读取数据信息,然后通过 service() 方法处理请求消息,并将处理后的响应数据写入到 HttpServletResponse 对象中。最后,Web 服务器会从 HttpServletResponse 对象中读取到响应数据,并发送给浏览器。

    需要注意的是,在 Web 服务器运行阶段,每个 Servlet 都只会创建一个实例对象,针对每次 HTTP 请求,Web 服务器都会调用所请求 Servlet 实例的 service(HttpServletRequest request,HttpServletResponse response)方法,并重新创建一个 request 对象和一个 response 对象

    HttpServletRequest详解:获取HTTP请求消息

    HttpServletRequest 接口继承自 ServletRequest 接口,其主要作用是封装 HTTP 请求消息。由于 HTTP 请求消息分为请求行、请求消息头和请求消息体三部分。因此,在 HttpServletRequest 接口中定义了获取请求行、请求头和请求消息体的相关方法。

    获取请求行信息的相关方法

    当访问 Servlet 时,所有请求消息将被封装到 HttpServletRequest 对象中,请求消息的请求行中包含请求方法、请求资源名、请求路径等信息,为了获取这些信息,HttpServletRequest 接口定义了一系列方法,如表 1 所示。
    在这里插入图片描述

    获取请求消息头的相关方法

    当浏览器发送 Servlet 请求时,需要通过请求消息头向服务器传递附加信息,例如,客户端可以接收的数据类型、压缩方式、语言等。为此,在 HttpServletRequest 接口中定义了一系列用于获取 HTTP 请求头字段的方法,如表 2 所示。
    在这里插入图片描述

    *获取form表单数据(参数)

    获取请求参数

    在实际开发中,经常需要获取用户提交的表单数据,例如用户名和密码等,为了方便获取表单中的请求参数,在 HttpServletRequest 接口的父类 ServletRequest 中定义了一系列获取请求参数的方法,如表 1 所示。
    在这里插入图片描述
    在表 1 中,getParameter() 方法用于获取某个指定的参数,而 getParameterValues() 方法用于获取多个同名的参数。下面通过具体的案例讲解这两个方法的使用:

    在 servletDemo02 项目的 WebContent 根目录下创建一个表单文件 form.html,编辑后如下所示。

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <form action="/servletDemo02/RequestsParamServlet" method="POST">
            用户名:<input type="text" name="username"><br/>&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"/><br/>
            <br/>
            爱好:
            <input type="checkbox" name="hobby" value="sing"/>唱歌
            <input type="checkbox" name="hobby" value="dance"/>跳舞
            <input type="checkbox" name="hobby" value="game"/>玩游戏
            <input type="submit" value="提交"/>
        </form>
    </body>
    </html>
    

    在 com.mengma.request 包中编写一个名称为 RequestParamsServlet 的 Servlet 类,使用该 Servlet 获取请求参数,如下所示。

    package com.mengma.servlet;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class RequestParamsServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            String name = request.getParameter("username");
            String password = request.getParameter("password");
            System.out.println("用户名" + name);
            System.out.println("密码" + password);
            // 获取参数名为"hobby"的值
            String[] hobbys = request.getParameterValues("hobby");
            System.out.println("爱好:");
            for (int i = 0; i < hobbys.length; i++) {
                System.out.println(hobbys[i] + ",");
            }
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    

    在 html 中,由于参数名为 hobby 的值可能有多个,因此,需要使用 getParameterValues() 方法获取多个同名参数的值,返回一个 String 类型的数组,通过遍历数组,输出每个 hobby 参数对应的值。

    启动 Tomcat 服务器,在浏览器的地址栏中输入地址 http://localhost:8080/servletDemo02/form.html 访问 form.html 页面,并填写表单的相关信息,填写后的页面如图 1 所示。
    在这里插入图片描述

    通过 Request 对象传递数据

    Request 对象不仅可以获取一系列数据,还可以通过属性传递数据。ServletRequest 接口中定义了一系列操作属性的方法。
    1)setAttribute() 方法
    该方法用于将一个对象与一个名称关联后存储到 ServletRequest 对象中,其完整语法定义如下:

    public void setAttribute(java.lang.String name,java.lang.Object o);
    

    需要注意的是,如果 ServletRequest 对象中已经存在指定名称的属性,则 setAttribute() 方法将会先删除原来的属性,然后再添加新的属性。如果传递给 setAttribute() 方法的属性值对象为 null,则删除指定名称的属性,这时的效果等同于 removeAttribute() 方法。
    2)getAttribute() 方法
    该方法用于从 ServletRequest 对象中返回指定名称的属性对象,其完整的语法定义如下:

    public java.lang.Object getAttribute(java.lang.String name);
    

    3)removeAttribute() 方法
    该方法用于从 ServletRequest 对象中删除指定名称的属性,其完整的语法定义如下:

    public void removeAttribute(java.lang.String name);
    

    4)getAttributeNames() 方法
    该方法用于返回一个包含 ServletRequest 对象中的所有属性名的 Enumeration 对象,在此基础上,可以对 ServletRequest 对象中的所有属性进行遍历处理。getAttributeNames() 方法的完整语法定义如下:

    public java.util.Enumeration getAttributeNames();
    

    需要注意的是,只有属于同一个请求中的数据才可以通过 ServletRequest 对象传递数据。

    RequestDispatcher实现请求转发

    当一个 Web 资源收到客户端的请求后,如果希望服务器通知另外一个资源处理请求,那么这时可以通过 RequestDispatcher 接口的实例对象实现。ServletRequest 接口中定义了一个获取 RequestDispatcher 对象的方法,如表 1 所示。
    在这里插入图片描述
    获取到 RequestDispatcher 对象后,最重要的工作就是通知其他 Web 资源处理当前的 Servlet 请求,为此,RequestDispatcher 接口定义了两个相关方法,如表 2 所示。

    表 2 RequestDispatcher 接口的方法
    在这里插入图片描述

    请求转发

    在 RequestDispatcher 接口中,forward() 方法可以实现请求转发,include() 方法可以实现请求包含,本节将以请求转发为例,讲解 forward() 方法的使用。

    在 Servlet 中,如果当前 Web 资源不想处理请求,则可以通过 forward() 方法将当前请求传递给其他的 Web 资源进行处理,这种方式称为请求转发。请求转发的工作原理如图 1 所示。

    从图 1 中可以看出,当客户端访问 Servlet1 时,可以通过 forward() 方法将请求转发给其他 Web 资源,其他 Web 资源处理完请求后,直接将响应结果返回到客户端。

    了解了 forward() 方法的工作原理后,下面通过案例演示 forward() 方法的使用。在 servletDemo02 项目的 com.mengma.request 包中创建一个名为 RequestForwardServlet 的 Servlet 类,该类使用 forword() 方法将请求转发到一个新的 Servlet 页面,如下所示。
    在这里插入图片描述

    package com.mengma.servlet;
    import java.io.IOException;
    import javax.servlet.*;
    import javax.servlet.http.*;
    public class RequestForwardServlet extends HttpServlet {
        public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            request.setAttribute("username", "张三");    // 将数据存储到request对象中
            RequestDispatcher dispatcher = request.getRequestDispatcher("/ResultServlet");
            dispatcher.forward(request,response);
        }
        public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
            doGet(request,response);
        }
    }
    

    在 RequestForwardServlet 中,通过使用 forward() 方法,将当前 Servlet 的请求转发到 ResultServlet 页面,在 com.mengma.request 包中编写一个名为 ResultServlet 的 Servlet 类,该类用于获取 RequestForwardServlet 类中存储在 request 对象中的数据并输出,ResultServlet 类的代码实现如下所示。

    package com.mengma.servlet;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class ResultServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            String username = (String) request.getAttribute("username");
            if (username != null) {
                out.println("用户名:" + username + "<br/>");
            }
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    

    启动 Tomcat 服务器,在浏览器的地址栏中输入地址 http://localhost:8080/servletDemo02/RequestForwardServlet 访问 RequestForwardServlet,浏览器的显示结果如图 2 所示。
    在这里插入图片描述
    从图 2 中可以看出,地址栏中显示的仍然是 RequestForwardServlet 的请求路径,但是浏览器却显示出了 ResultServlet 中要输出的内容。这是因为请求转发是发生在服务器内部的行为,从 RequestForwardServlet 到 ResultServlet 属于一次请求,在一次请求中是可以使用 request 属性进行数据共享的。

    HttpServletResponse详解

    HttpServletResponse 接口继承自 ServletResponse 接口,主要用于封装 HTTP 响应消息。由于 HTTP 响应消息分为状态行、响应消息头、消息体三部分。因此,在 HttpServletResponse 接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法,本节将针对这些方法进行详细讲解。

    发送状态码相关的方法

    当 Servlet 向客户端回送响应消息时,需要在响应消息中设置状态码。因此,HttpServletResponse 接口定义了两个发送状态码的方法。
    1)setStatus(int status)方法
    该方法用于设置 HTTP 响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而 HTTP 版本由服务器确定,因此,只要通过 setStatus(int status)方法设置了状态码,即可实现状态行的发送。需要注意的是,在正常情况下,Web 服务器会默认产生一个状态码为 200 的状态行。
    2)sendError(int sc)方法
    该方法用于发送表示错误信息的状态码。例如,404 状态码表示找不到客户端请求的资源。response 对象提供了两个重载的 sendError(int sc)方法,具体如下:

    public void sendError(int code) throws java.io.IOException
    public void sendError(int code,String message)throws java.io.IOException
    

    在上面重载的两个方法中,第一个方法只发送错误信息的状态码,而第二个方法除了发送状态码以外,还可以增加一条用于提示说明的文本信息,该文本信息将出现在发送给客户端的正文内容中。

    发送响应消息头相关的方法

    Servlet 向客户端发送的响应消息中包含响应头字段,由于 HTTP 协议的响应头字段有很多种,因此,HttpServletResponse 接口定义了一系列设置 HTTP 响应头字段的方法,如表 2 所示。
    在这里插入图片描述
    需要注意的是,在表 1 列举的一系列方法中,addHeader()、setHeader()、addIntHeader()、setIntHeader() 方法都用于设置各种头字段,而 setContetType()、setLoacale() 和 setCharacterEncoding() 方法用于设置字符编码,这些设置字符编码的方法可以有效解决乱码问题。

    发送响应消息体相关的方法

    由于在 HTTP 响应消息中,大量的数据都是通过响应消息体传递的,因此,ServletResponse 遵循以 I/O 流传递大量数据的设计理念。在发送响应消息体时,定义了两个与输出流相关的方法。
    由于在 HTTP 响应消息中,大量的数据都是通过响应消息体传递的,因此,ServletResponse 遵循以 I/O 流传递大量数据的设计理念。在发送响应消息体时,定义了两个与输出流相关的方法。
    1)getOutputStream() 方法
    该方法所获取的字节输出流对象为 ServletOutputStream 类型。由于 ServletOutputStream是OutputStream 的子类,它可以直接输出字节数组中的二进制数据。因此,要想输出二进制格式的响应正文,就需要使用 getOutputStream() 方法。
    2)getWriter() 方法
    该方法所获取的字符输出流对象为 PrintWriter 类型。由于 PrintWriter 类型的对象可以直接输出字符文本内容,因此,要想输出内容全部为字符文本的网页文档,则需要使用 getWriter() 方法。

    注意: 虽然 response 对象的 getOutputStream() 和 getWriter() 方法都可以发送响应消息体,但是,它们之间互相排斥,不可同时使用,否则会发生 IllegalStateException 异常。

    response.sendRedirect()实现重定向(页面跳转)

    在某些情况下,针对客户端的请求,一个 Servlet 类可能无法完成全部工作。这时,可以使用请求重定向完成这一工作。

    请求重定向指 Web 服务器接收到客户端的请求后,可能由于某些条件的限制,不能访问当前请求 URL 所指向的 Web 资源,而是指定了一个新的资源路径,让客户端重新发送请求。

    为了实现请求重定向,HttpServletResponse 接口定义了一个 sendRedirect() 方法,该方法用于生成 302 响应码和 Location 响应头,从而通知客户端重新访问 Location 响应头中指定的 URL,sendRedirect() 方法的完整语法如下所示:
    public void sendRedirect(java.lang.String location) throws java.io.IOException

    在上述方法代码中,参数 location 可以使用相对 URL,Web 服务器会自动将相对 URL 翻译成绝对 URL,再生成 Location 头字段。

    sendRedirect() 方法的工作原理如图 1 所示。

    在这里插入图片描述
    在图 1 中,当客户端访问 Servlet1 时,由于在 Servlet1 中调用了 sendRedirect() 方法将请求重定向到 Servlet2,因此,浏览器收到 Servlet1 的响应消息后,立刻向 Servlet2 发送请求,Servlet2 对请求处理完毕后,再将响应消息回送给客户端浏览器并显示。

    package com.mengma.servlet;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class LoginServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            // 用 HttpServletRequest 对象的 getParameter() 方法获取用户名和密码
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            // 假设用户名和密码分别为 admin 和 123456
            if ("admin".equals(username) && ("123456").equals(password)) {
                // 如果用户名和密码正确,重定向到 welcome.html
                response.sendRedirect("/servletDemo02/welcome.html");
            } else {
                // 如果用户名和密码错误,重定向到 login.html
                response.sendRedirect("/servletDemo02/login.html");
            }
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            doGet(request, response);
        }
    }
    

    Java Servlet的request/response中文乱码问题的解决方案

    Request中文乱码问题以及解决方案

    request.setCharacterEncoding("utf-8");  //设置request对象的解码方式
    

    这种解决乱码的方式只对 POST 方式有效,而对 GET 方式无效。为了解决 GET 方式提交表单时出现的中文乱码问题,可以先使用错误码表 ISO-8859-1 将用户名重新编码,然后使用码表 UTF-8 进行解码。

    name = new String(name.getBytes("iso8859-1"),"utf-8");
    

    Response中文乱码问题以及解决方案
    由于计算机中的数据都是以二进制形式存储的,因此,当传输文本数据时,会发生字符和字节之间的转换。字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,则会导致乱码问题。

    在 servletDemo02 项目中新建一个名称为 com.mengma.response 的包,在该包中新建一个名为ChineseServlet 的类,在类中定义一个中文字符串,然后使用字符输出流输出,如下所示。

    package com.mengma.servlet;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class ChineseServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            String data = "中国";
            PrintWriter out = response.getWriter();
            out.println(data);
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            doGet(request, response);
        }
    }
    

    浏览器显示的内容是“??”,说明发生了乱码。实际上此处产生乱码的原因是 response 对象的字符输出流在编码时采用的字符码表是 ISO-8859-1,该码表不兼容中文,会将“中国”编码为 63 63(在 ISO-8859-1 的码表中查不到的字符就会显示 63)。当浏览器对接收到的数据进行解码时,会采用默认的码表 GB2312,将 63 解码为?,因此,浏览器将“中国”两个字符显示为“??”

    为了解决上述编码错误,HttpServletResponse 对象提供了两种解决乱码的方式,具体如下。

    第一种方式:

    response.setCharacterEncoding("utf-8");    //设置 HttpServletResponse使用utf-8编码
    response.setHeader("Content-Type", "text/html;charset=utf-8");    //通知浏览器使用utf-8解码
    

    第二种方式:

    response.setContentType("text/html;charset=utf-8");    //包含第一种方式的两个功能
    

    在通常情况下,为了使代码更加简洁,一般会采用第二种方式。

    J

    Servlet Filter(过滤器)是什么?它的方法有哪些?

    Filter是Servlet的过滤器,是Servlet 2.3规范中新增加的一个功能,主要用于完成一些通用的操作,如编码的过滤、判断用户的登录状态等。

    在现实生活中,人们可以使用污水净化设备对水源进行过滤净化。同样,在程序中人们也可以使用 Filter 对请求和响应信息进行过滤。

    Filter 被称为过滤器,其主要作用是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊功能。Filter 在 Web 应用中的拦截过程如图 1 所示。
    在这里插入图片描述
    在图 1 中,当用户通过浏览器访问服务器中的目标资源时,首先会被 Filter 拦截,在 Filter 中进行预处理操作,然后再将请求转发给目标资源。当服务器接收到这个请求后会对其进行响应,在服务器处理响应的过程中,也需要将响应结果经过滤器处理后,才发送给客户端。

    本质上,Filter 过滤器就是一个实现了 javax.servlet.Filter 接口的类,在 javax.servlet.Filter 接口中定义了三个方法,如表 1 所示。
    在这里插入图片描述
    表 1 中的三个方法都是可以表现 Filter 生命周期的方法,其中 init() 方法在 Web 应用程序加载时会被调用,destroy() 方法在 Web 应用程序卸载(或关闭)时被调用,这两个方法都只会被调用一次,而 doFilter() 方法会被调用多次(只要客户端有请求时就会被调用),Filter 所有的工作集中在 doFilter() 方法中。

    第一个Filter程序

    为了帮助读者快速了解 Filter 的开发过程,下面通过案例演示 Filter 程序如何对 Servlet 程序的调用过程进行拦截。
    1)创建 Servlet
    在 MyEclipse 中创建一个名为 filterDemo01 的 Web 项目,并在项目的 src 下创建一个名为 com.mengma.filter 的包,在该包中创建一个名为 MyServlet 的 Servlet 类,该类用于访问时在浏览器中输出“Hello MyServlet”。MyServlet 类的实现代码如下所示。

    package com.mengma.filter;
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class MyServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.getWriter().write("Hello MyServlet");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    

    2)创建 Filter 类

    package com.mengma.filter;
    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    @WebFilter("/MyServlet")
    public class MyFilter implements Filter {
        public MyFilter() {
        }
        public void destroy() {
        }
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            chain.doFilter(request, response);
        }
        public void init(FilterConfig fConfig) throws ServletException {
        }
    }
    

    在上述代码中,MyFilter() 是 MyFilter 类默认的构造方法,其他三个方法是 Filter 接口中的方法。在 doFilter() 方法中,chain.doFilter(request,response)用于过滤处理,表示将请求向下传递。

    使用 MyEclipse 创建过滤器类后,需在 web.xml 中创建过滤器信息,代码如下:

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>com.mengma.filter.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/MyServlet</url-pattern>
    </filter-mapping>
    

    在上述代码中,设置了过滤器对 /MyServlet 请求资源进行拦截,将在请求到达 MyServlet 程序前执行 MyFilter 程序。过滤器的配置信息中包含多个元素,这些元素分别具有不同的作用。

    • 根元素用于注册一个 Filter。
    • 子元素用于设置 Filter 名称。
    • 子元素用于设置 Filter 类的完整名称。
    • 根元素用于设置一个过滤器所拦截的资-源。
    • 子元素必须与 中的 子元素相同。
    • 子元素用于匹配用户请求的 URL,例如 /MyServlet,这个 URL 还可以使用通配符*表示,例如 *.do 适用于所有以 .do 结尾的 Servlet 路径。
      3)修改 Filter
      为了演示 Filter 的拦截效果,对 MyFilter 类中的 doFilter() 方法进行修改,修改后的代码如下:
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        PrintWriter out = response.getWriter();
        out.write("Hello MyFilter");
    }
    

    4)运行项目并查看结果
    启动 Tomcat 服务器,在浏览器的地址栏中输入地址 http://localhost:8080/filterDemo01/MyServlet 访问 MyServlet,此时,浏览器窗口显示的结果如图 2 所示。
    在这里插入图片描述
    从图 2 中可以看出,在使用浏览器访问 MyServlet 时,浏览器窗口中只显示了 MyFilter 的输出信息,而没有显示 MyServlet 的输出信息,这说明 MyFilter 成功拦截了 MyServlet 程序。

    Java Servlet Filter的两种映射方式

    1)使用通配符*拦截用户的所有请求

    2)拦截不同方式的访问请求
    在 web.xml 文件中,每一个 元素都可以配置一个 Filter 所负责拦截的资源。在 元素中有一个特殊的子元素 ,该元素用于指定过滤器所拦截的资源被 Servlet 容器调用的方式。 元素的值共有四个,如表 1 所示。
    在这里插入图片描述
    为了让读者更好地理解表 1 中的四个值的作用,下面以 FORWARD 为例,分步骤演示 Filter 对转发请求的拦截效果。
    例子:
    在 filterDemo01 项目的 com.mengma.filter 包中创建一个名为 ForwardServlet 的 Servlet 类,该类用于将请求转发给 first.jsp 页面,如下所示。

    public class ForwardServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            request.getRequestDispatcher("/first.jsp").forward(request, response);
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    

    此时需在 web.xml 文件中添加 ForwardFilter 的映射信息。代码中增加了一个 子元素,并且该元素的值为 FORWARD,如下所示:

    <filter>
        <filter-name>ForwardFilter</filter-name>
        <filter-class>com.mengma.filter.ForwardFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ForwardFilter</filter-name>
        <url-pattern>/first.jsp</url-pattern>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    

    结果浏览器窗口显示的是 ForwardFilter 类中的内容,而 first.jsp 页面的输出内容没有显示。由此可见,ForwardServlet 中通过 forward() 方法转发的 first.jsp 页面被成功拦截。

    FilterChain(过滤器链)详解

    在一个 Web 应用程序中可以注册多个 Filter 程序,每个 Filter 程序都可以针对某一个 URL 进行拦截。如果多个 Filter 程序都对同一个 URL 进行拦截,那么这些 Filter 就会组成一个Filter 链(也称过滤器链)。

    Filter 链用 FilterChain 对象表示,FilterChain 对象中有一个 doFilter() 方法,该方法的作用是让 Filter 链上的当前过滤器放行,使请求进入下一个 Filter。

    Filter 链的拦截过程如图 1 所示。
    在这里插入图片描述
    在图 1 中,当浏览器访问 Web 服务器中的资源时,需要经过两个过滤器 Filter1 和 Filter2。首先 Filter1 会对这个请求进行拦截,在 Filter1 中处理完请求后,通过调用 Filter1 的 doFilter() 方法将请求传递给 Filter2,Filter2 处理用户请求后同样调用 doFilter() 方法,最终将请求发送给目标资源。当 Web 服务器对这个请求做出响应时,也会被过滤器拦截,但这个拦截顺序与之前相反,最终将响应结果发送给客户端浏览器。

    为了便于读者理解 Filter 链的拦截过程以及掌握 Filter 链的使用,下面通过案例演示如何使用 Filter 链拦截 MyServlet 的同一个请求。
    1)创建过滤器
    在 filterDemo01 项目的 com.mengma.filter 包中新建两个过滤器 MyFilter01 和 MyFilter02,如 MyFilter01 和 MyFilter02 所示。
    ① MyFilter01

    public class MyFilter01 implements Filter {
        public void init(FilterConfig fConfig) throws ServletException {
            // 过滤器对象在初始化时调用,可以配置一些初始化参数
        }
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,则该方法会被调用
            PrintWriter out = response.getWriter();
            out.write("MyFilter01<br/>");
            chain.doFilter(request, response);
        }
        public void destroy() {
            // 过滤器对象在销毁时自动调用,释放资源
        }
    }
    

    ② MyFilter02

    public class MyFilter02 implements Filter {
        public void init(FilterConfig fConfig) throws ServletException {
            // 过滤器对象在初始化时调用,可以配置一些初始化参数
        }
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,则该方法会被调用
            PrintWriter out = response.getWriter();
            out.write("MyFilter02 Before<br/>");
            chain.doFilter(request, response);
            out.write("<br/>MyFilter02 After<br/>");
        }
        public void destroy() {
            // 过滤器对象在销毁时自动调用,释放资源
        }
    }
    

    2)修改 web.xml
    为了防止其他过滤器影响此次 Filter 链的演示效果,需要先将 web.xml 文件中的其他过滤器的配置信息注释掉,然后将 MyFilter01 和 MyFilter02 过滤器的映射信息配置在 MyServlet 配置信息前面,具体如下所示。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
        <filter>
            <filter-name>MyFilter01</filter-name>
            <filter-class>com.mengma.filter.MyFilter01</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>MyFilter01</filter-name>
            <url-pattern>/MyServlet</url-pattern>
        </filter-mapping>
        <filter>
            <filter-name>MyFilter02</filter-name>
            <filter-class>com.mengma.filter.MyFilter02</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>MyFilter02</filter-name>
            <url-pattern>/MyServlet</url-pattern>
        </filter-mapping>
        <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>com.mengma.filter.MyServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/MyServlet</url-pattern>
        </servlet-mapping>
    </web-app>
    

    3)运行项目并查看结果
    启动 Tomcat 服务器,在浏览器的地址栏中输入 http://localhost:8080/filterDemo01/MyServlet,此时,浏览器窗口中的显示结果如图 2 所示。

    在这里插入图片描述
    从图 2 中可以看出,MyServlet 首先被 MyFilter01 拦截了,显示出 MyFilter01 中的内容,然后被 MyFilter02 拦截,直到 MyServlet 被 MyFilter02 放行后,浏览器才显示出 MyServlet 中的输出内容。

    需要注意的是,Filter 链中各个 Filter 的拦截顺序与它们在 web.xml 文件中 < filter-mapping> 元素的映射顺序一致,由于 MyFilter01 的 < filter-mapping> 元素位于 MyFilter02 的 < filter-mapping> 元素前面,因此,用户的访问请求首先会被 MyFilter01 拦截,然后再被 MyFilter02 拦截。

    FilterConfig接口及其使用方法详解

    FilterConfig 是 Servlet API 提供的一个用于获取 Filter 程序在 web.xml 文件中的配置信息的接口,该接口封装了 Filter 程序在 web.xml 中的所有注册信息,并且提供了一系列获取这些配置信息的方法,具体如表 1 所示。
    在这里插入图片描述
    表 1 列举了 FilterConfig 接口中的一系列方法,为了让读者更好地掌握这些方法,下面以 getInitParameter(String name)方法的使用为例演示 FilterConfig 接口的使用。
    1)创建过滤器
    在 filterDemo01 项目的 com.mengma.filter 包中创建过滤器 MyFilter03,使用该过滤器获取 web.xml 中设置的参数,如下所示。
    在这里插入图片描述

    Servlet Filter实现全站统一编码,解决中文乱码问题

    在开发 Web 项目时,解决中文乱码问题是不可避免的。在前面所学的知识中,解决乱码的通常做法是在 Servlet 程序中设置编码方式,但是,当多个 Servlet 程序都需要设置编码方式时,就会书写大量重复的代码。

    为了解决这一问题,我们可以在 Filter 中对获取到的请求和响应消息进行编码处理,这样就可以实现全站编码方式的统一。本节将分步骤演示如何使用 Filter 实现全站编码的统一。

    创建过滤器

    package com.mengma.filter;
    
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    
    public class CharacterFilter implements Filter {
        public void init(FilterConfig fConfig) throws ServletException {
    
        }
    
        public void doFilter(ServletRequest req, ServletResponse res,
                FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            // 拦截所有的请求,解决全站中文乱码,指定request和response的编码
            request.setCharacterEncoding("utf-8"); // 只对消息体有效
            response.setContentType("text/html;charset=utf-8");
            // 对 request 进行包装
            CharacterRequest characterRequest = new CharacterRequest(request);
            chain.doFilter(characterRequest,response);
        }
    
        public void destroy() {
        }
    
    }
    
    // 继承默认包装类 HttpServletRequestWrapper
    class CharacterRequest extends HttpServletRequestWrapper {
        private HttpServletRequest request;
    
        public CharacterRequest(HttpServletRequest request) {
            super(request);
            this.request = request;
        }
    
        // 子类继承父类一定会覆写一些方法,此处用于重写getParameter()方法
        public String getParameter(String name) {
            // 调用被包装对象getParameter()方法,获得请求参数
            String value = super.getParameter(name);
            if (value == null) {
                return null;
            }
            String method = super.getMethod(); // 判断请求方式
            if ("get".equalsIgnoreCase(method)) {
                try {
                    value = new String(value.getBytes("iso-8859-1"), "utf-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
            return value; // 解决乱码后返回结果
    
        }
    }
    

    Servlet事件监听器是什么?

    Servlet 事件监听器是一个实现了特定接口的 Java 程序,这个程序专门用于监听 Web 应用中 ServletContext、HttpSession 和 ServletRequest 等域对象的创建和销毁过程、监听这些域对象属性的修改以及感知绑定到 HttpSession 域中的某个对象的状态。

    根据监听事件的不同,可以将表中的监听器分为如下三类。

    1)用于监听域对象创建和销毁的事件监听器(ServletContextListener 接口、HttpSessionListener 接口、ServletRequestListener 接口)。

    2)用于监听域对象属性增加和删除的事件监听器(ServletContextAttributeListener 接口、HttpSessionAttributeListener 接口、ServletRequestAttributeListener 接口)。

    3)用于监听绑定到 HttpSession 域中某个对象状态的事件监听器(HttpSessionBindingListener 接口、HttpSessionActivationListener 接口)。

    在 Servlet 规范中,这三类事件监听器都定义了相应的接口,在编写事件监听器程序时只需实现对应的接口即可。在使用监听程序时,Web 服务器会根据监听器所实现的接口,把它注册到被监听的对象上,当触发了某个对象的监听事件时,Web 容器将会调用 Servlet 监听器与之相关的方法对事件进行处理。

    Servlet HttpSessionListener监听器统计网站在线人数

    创建一个实现了 HttpSessionListener 接口的监听器类 OnlineListener,在该类中编写用于实现统计网站在线人数的代码

    public class OnlineListener implements HttpSessionListener {
        private int count = 0; // 用于统计在线人数
        @Override
        public void sessionCreated(HttpSessionEvent hse) {
            count++; // Session对象创建时count变量加1
            ServletContext context = hse.getSession().getServletContext();
            context.setAttribute("count", new Integer(count));
        }
        @Override
        public void sessionDestroyed(HttpSessionEvent hse) {
            count--; // session对象销毁时count变量减1
            ServletContext context = hse.getSession().getServletContext();
            context.setAttribute("count", new Integer(count));
        }
    }
    

    在 OnlineListener.java 中,首先定义了一个用于统计在线人数的成员变量 count。当每次监听到 HttpSession 对象创建时,count 成员变量会加 1。当每次监听到 HttpSession 对象销毁时,count 成员变量会减 1。

    在每次修改 count 成员变量后,还应该将 count 成员变量的值保存到 ServletContext 对象中,以便其他 JSP 页面程序可以从 ServletContext 对象中取出 count 成员变量,从而在页面上显示当前在线用户数量。

    需要注意的是,这个 HttpSession 对象在不活动时的最长存活时间仍然是 2min

    原内容出处

    http://c.biancheng.net/servlet/

    展开全文
  • Servlet 入门理解

    千次阅读 2014-10-09 22:00:37
    当学到一个新技术的时候,不是

       当学到Servlet这个新技术的时候,不是着急去学Servlet这个java类有什么属性、方法,而是先去了解这个东西什么时候会用到,既然都是BS的,那ASP.NET中有没有类似的?然后就有了我的这篇博客。


       1.Servlet产生背景和主要作用

       我们都知道网页有静态和动态之分。静态的只能看看,而动态可以实现客户端和服务器的交互,比如登录的功能,我们输入用户名和密码后提交到服务器,服务器会处理这些信息,如果正确的话则进入主页。若不正确,则给出提示信息。这是我们很常实现的例子,可是我们有没有想过:客户端到服务器之间这个交互的过程是怎么实现的?之前我没有想过。直到遇到了Servlet.Servlet是Java中用来处理BS架构下,客户端请求的响应处理。


       2.java中Servlet和ASP.net中的HttpHandler的对比

    ASP.NET:

       当一个HTTP请求经同HttpModule容器传递到HttpHandler容器中时,ASP.NET Framework会调用HttpHandlerProcessRequest成员方法来对这个HTTP请求进行真正的处理。以一个ASPX页面为例,正是在这里一个ASPX页面才被系统处理解析,并将处理完成的结果继续经由HttpModule传递下去,直至到达客户端。我们看一张图帮助理解:


    Java:

       在这个过程中,HttpServletRequest和HttpServletReponse相当于上面的HttpModule起到传过去,传回来的作用。Servlet(HttpServlet)相当于HttpHandler处理客户端请求。


    3.Servlet是什么

    现在我们说说Servlet是什么。Servlet就是一个Java类。类就会有一系列的属性和方法。了解这些可以看详细的API文档。这里不再赘述。

    Java包组成:javax.servlet和javax.servlet.http. 在javax.servlet包中定义了所有的Servlet类都必须实现或扩展的的通用接口和类.在javax.servlet.http包中定义了采用HTTP通信协议的HttpServlet类.


    4.Demo(Tomcat)

    login.html

    <html>
    	<head>
    		<title>Login</title>
    	</head>
    	<body>
    		<form action="exam/login">
    		用户名:<input type="text" name="username"> <br>
    		密 码:<input type="password" name="password"> <br>
    		<input type="submit" value="登录">
    		</form>
    	</body>
    </html>

    web.xml

    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       version="2.5"> 
    
    	 <servlet>
    	 	<servlet-name>MyServlet</servlet-name>
    	 	<servlet-class>loginservlet</servlet-class>
    	 </servlet>
    	 <servlet-mapping>
    	 	<servlet-name>MyServlet</servlet-name>
    	 	<url-pattern>/login</url-pattern>
    	 </servlet-mapping>
    	 
    	 <servlet>	 
    
    </web-app>
    loginServlet.java

    import javax.servlet.http.*;
    import javax.servlet.*;
    import java.io.*;
    
    public class loginservlet extends HttpServlet{
    	public void doGet(HttpServletRequest req,
                         HttpServletResponse resp)
                  throws ServletException,
                         IOException{
              String username = req.getParameter("username");
              String password = req.getParameter("password");
              
              System.out.println("username = " + username );
              System.out.println("password = " + password );
              
              resp.setContentType("text/html");
              resp.getWriter().println("Login Success!");
      }             
    }
    对应时序图:


       总结:以前没有想过客户端和服务器如何实现交互。Servlet开始让我思考。学习不能总是看以前学得不扎实。学得时候做好总结,往前看。但学新的东西要联系旧的东西,这样既能巩固旧知识,也能使学习变得轻松。这也是为什么我们学了后面的,再看前面学得容易了的原因。

    展开全文
  • Servlet入门实践

    千次阅读 2015-11-20 09:28:35
    本文主要介绍servlet,包括入门到升入,基本上可以对servlet有一个很好的认识;
  •  通过前面两个章节的铺垫,本章正式迈入Servlet的学习 方法 1.概念 我们知道,有了http协议,规定了web交互的基本规范。有了服务器,用户的请求能够实时的得到响应。那么现在有个问题,就是用户发送一个请求给...
  • Servlet入门(一)

    万次阅读 多人点赞 2018-08-20 23:54:15
    1.Servlet的基本概念: Servlet定义:Servlet是基于Java技术的Web组件,由容器管理并产生动态的内容。Servlet与客户端通过Servlet容器实现的请求/响应模型进行交互。 注意:Servlet不是从命令行启动的,而是由包含...
  • servlet 是在服务器上运行的小程序,一个 servlet 就是一个 Java 类,并且可以通过 “请求 - 响应” 编程模式来访问这个驻留在服务器内存里面的 servlet 程序 tomcat 容器等级以及 servlet 的位置 二、编写 ...
  • servlet入门

    2013-07-17 10:18:09
    简介:Servlet是sun公司提供的一门用于开发动态web资源的技术。Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤: 1、编写一个...
  • Servlet入门简单介绍

    2017-08-11 19:45:13
    Servlet简介 1、Servlet是服务器端的重要组件,直译为服务端的小程序,它属于动态资源,用来处理请求,服务器接收到请求后会调用Servlet来处理请求。 2、Servlet的主要作用:接收请求;处理请求; 完成响应。 当...
  • Servlet入门实战

    万次阅读 2016-09-14 10:56:58
    Servlet 什么是ServletServlet=Server+Applet.Servlet是运行在服务器端的java应用程序,它独立于平台和协议。可以生成动态的web 页面。它是客户端请求和服务器响应的中间层。 Servlet和CGI(公共网关接口)相比...
  • Tomcat与Servlet入门

    2017-08-29 00:04:02
    使用Tomcat发布一个WEB工程:Tomcat的安装及目录结构 【下载Tomcat】 http://tomcat.apache.org/download-70.cgi 【安装Tomcat】 解压即可,tomcat不要放在中文目录下 【了解Tomcat的目录结构】 ...*
  • 【Servlet】servlet入门

    2013-11-22 10:11:19
    新建一个项目,点击 src 选择 New|Servlet .创建一个FirstSer.java文件 package com.servlet;import java.io.IOException;...import javax.servlet.ServletException; import javax.servlet.http.HttpServl
  • jsp+servlet实现班级信息管理项目
  • 教你Servlet入门

    千次阅读 热门讨论 2015-03-24 14:44:12
    Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础。这篇博客主要帮助大家了解一个 Web 工程在 Servlet 容器中是如何启动的? Servlet 容器如何解析你在 web.xml 中定义的 ...
  • 林炳文Evankaka原创作品。...一了解Servlet的概念二Servlet技术功能三 Servlet技术特点四 Servlet生命周期五servlet工作过程六 Servlet与JSP区别七Servlet代码结构八 Servlet第一个程序 一、了解Servlet的概念  Se
  • 工程名为ServletExample     点击Finish,建立maven项目完成如下       生成后的目录没有java源码目录,按照maven的约定,还要新建src/main/java的源码目录。选中项目,点击鼠标右键     不...
  • SIP Servlet入门教程及例子

    万次阅读 2010-08-16 14:05:00
    作为一个SIP Servlet Tutorial,这个文档主要描述了在JavaEE平台下如何开发基于SIP协议的应用服务。当然这个教程也包含了如何将JavaEE技术与SIP应用程序集成。 这个教程主要涉及到的软件有: 1. ...
  • Servlet入门之HelloWorld

    千次阅读 2015-10-03 17:24:08
    Servlet入门之HelloWorld 一、环境准备 1.下载并安装Tomcat。 apache-tomcat-7.0.64-windows-i64.zip 2.设置Tomcat环境变量。 在环境变量中添加: CATALINA={$tomcat_path} 并在CLASS_PATH中...
  • 工欲善其事、必先利其器,想要成为JavaWEB高手那么你不知道servlet是一个什么玩意的话,那就肯定没法玩下去,那么servlet究竟是个什么玩意?下面,仅此个人观点并通过一个小小的案例来为大家详述一下什么是servlet.....
1 2 3 4 5 ... 20
收藏数 58,434
精华内容 23,373
关键字:

servlet入门