百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

简单说说Servlet,并分析面试官喜欢的Servlet执行原理

yuyutoo 2024-11-05 13:26 3 浏览 0 评论

Servlet


Servlet简介

Server + let 意为:运行在服务器端的小程序。 Servlet实际上就是一个接口。

  • 狭义上的Servlet,指的就是Servlet接口
  • 广义上的我们认为凡是实现Servlet接口的类,我们都称他是一个Servlet *****
  • Servlet的作用:*
  1. 接收用户发送的请求
  2. 调用其他的java程序来处理请求
  3. 根据处理结果,返回给用户一个页面

Servlet的HelloWorld

  1. 创建一个类并实现Servlet接口
  2. 在web.xml文件中对Servlet进行配置
       <servlet>
            <servlet-name>别名</servlet-name>
            <servlet-class>全类名</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>别名</servlet-name>
            <url-pattern>需要servlet处理的请求地址</url-pattern>
        </servlet-mapping>

 **Servlet的三个名字**:

        <servlet-name>
            - Servlet的别名,程序员通过别名对Servlet进行配置
        <servlet-class>
            - Servlet的全类名,服务器通过全类名来创建Servlet的实例
        <url-pattern>
            - Servlet映射的请求地址,用户通过该地址访问Servlet

Servlet的生命周期

Servlet的生命周期,指Servlet的对象从被创建到被销毁的过程。

Servlet的生命周期方法

1.构造器

  • Servlet第一次处理请求时,会调用构造器,来创建Servlet实例。
  • 只会调用一次,Servlet是单例模式,它是以多线程的方式调用service()方法.
  • -Servlet不是线程安全,所以尽量不要在service()方法中操作全局变量
  • 2.init()方法*
  • 构造器调用之后马上被调用,用来初始化Servlet,只会调用一次
  • 3.service()方法*
  • Servlet每次处理请求时都会调用service()方法,用来处理请求,会调用多次。
  • 4.destroy()方法*
  • Servlet对象销毁前(WEB项目卸载时)调用,用来做一些收尾工作,释放资源。

相关接口

ServletConfig 代表:当前Servlet的配置信息,每一个Servlet都有其唯一对应的ServletConfig。

<servlet>
                <servlet-name>AServlet</servlet-name>
                <servlet-class>com.atguigu.servlet.AServlet</servlet-class>
                <init-param>
                    <param-name>user</param-name>
                    <param-value>root</param-value>
                </init-param>
                <init-param>
                    <param-name>password</param-name>
                    <param-value>123123</param-value>
                </init-param>
            </servlet>

获取:由Tomcat服务器创建,最终作为参数传递到init()方法中,我们可以在init()方法直接使用。 当我们通过继承HttpServlet创建Servlet时,由于父类已经实现ServletConfig接口, 所以我们可以在Servlet中直接调用ServletConfig的方法。

功能:

  1. 获取Servlet的别名
  2. 获取当前Servlet的初始化参数。
<init-param>
 <param-name>user</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
 <param-name>password</param-name>
<param-value>123123</param-value>
</init-param>
  1. 获取当前WEB应用的ServletContext对象。

ServletContext

代表:当前的WEB应用,一个WEB应用对应一个唯一的ServletContext对象, ServletContext对象在项目启动时创建,在项目卸载时销毁。

获取:通过ServletConfig的getServletContext()方法获取。

功能: 【1】 可以获取整个WEB应用的初始化参数

 <context-param>
                <param-name>phone</param-name>
                <param-value>1388888888</param-value>
            </context-param>

【2】 可以获取资源的真实路径(物理路径),主要在文件的上传和下载时使用。 【3】可以作为一个域对象在不同的web资源之间共享数据。

GenericServlet

  • 通用Servlet的父类
  • 相比Servlet接口GenericServlet更加简单一些,但是我们最终实际上使用的HttpServlet

HttpServlet

  • HttpServlet继承了GenericServlet,而GenericServlet实现Servlet接口
  • 所以我们可以同构继承HttpServlet来创建一个Servlet。
  • HttpServlet重写service()方法:
  1. 在该方法中先将ServletRequest和ServletResponse 强转为了HttpServletRequest和HttpServletResponse。然调用重载的service()方法,并将刚刚强转得到对象传递到重载的方法中。 如果是GET请求,则调用doGet(HttpServletRequest request , HttpServletResponse response) 如果是post请求,则调用doPost(HttpServletRequest request , HttpServletResponse response)
  • 结论: 当通过继承HttpServlet来创建一个Servlet时,我们只需要根据要处理的请求的类型,来重写不同的方法。 处理get请求,则重写doGet() 处理post请求,则重写doPost()[6]

HttpServletRequest

代表:

   浏览器发送给服务器的请求报文。

获取:

该对象由Tomcat服务器创建,最终作为参数传递到doGet或doPost方法中,我们可以在这两个方法中直接使用。 功能:

【1】获取用户发送的请求参数 request.getParameter("username"); 【2】获取项目的名字(用来设置绝对路径) request.getContextPath(); 【3】作为一个域对象,在不同的WEB资源之间共享数据。 【4】请求的转发 request.getRequestDispatcher("target.html").forward(request, response);

HttpServletResponse

代表: 服务器发送给浏览器的响应报文。 获取: 该对象由Tomcat服务器创建,最终作为参数传递到doGet或doPost方法中,我们可以在这两个方法中直接使用。 功能: 【1】响应给浏览器一个网页或者是网页片段(设置的是响应报文的响应体) response.getWriter(""); 【2】请求的重定向 response.sendRedirect("target.html")

转发和重定向:(掌握)

                        转发                重定向
    请求的次数:          1                      2
    发生的位置            服务器内部            浏览器
    浏览器地址栏        不改变                改变
    浏览器的感知        不知道                知道   

字符编码

    > 当用户通过表单向Servlet发送中文请求参数时,Servlet获取到内容会产生乱码,
        当Servlet向浏览器响应中文内容时,也会产生乱码。
    > 浏览器和服务器之间通信时,中文内容时不能直接发送的,需要对中文进行编码。
    > 编码:
        - 将字符转换为二进制码的过程叫编码。
    > 解码:
        - 将二进制码转换为普通字符的过程叫解码。
    > 编码和解码所采用的规则我们称为字符集。

    > 产生乱码问题的根本原因:
        编码和解码所采用的字符集不同。

    > 解决方法:
        统一编码和解码的字符集为UTF-8。

    > 常见字符集:
        1.ASCII
        2.ISO8859-1
        3.GBK
        4.GB2312
        5.UTF-8

    > 请求编码
        - 请求是浏览器发送给服务器的。
        - 浏览器 --> 服务器
        - 浏览器 编码
            > 浏览器的会自动使用网页的字符集对参数进行编码
              UTF-8的张三:%E5%BC%A0%E4%B8%89
              GBK的张三:%D5%C5%C8%FD

            > 所以我们只需要统一网页的字符集为UTF-8即可。

        - 服务器 解码
            post请求
                > request解码时默认字符集时iso8859-1,但是iso压根就不支持中文
                > post请求在servlet中解码,所以我们只需要指定request的字符集即可。
                > 我们可以通过如下方法,来设置request的字符集:
                    request.setCharacterEncoding("utf-8");
                > 注意:
                    该方法要在request.getParameter()第一次调用之前调用

            get请求
                > get请求是通过url地址传递请求参数,url中的请求参数将会被Tomcat服务器自动解码。
                > Tomcat的默认编码是iso8859-1,但是iso压根就不支持中文,所以必然乱码。
                > 只需要修改Tomcat的解码的默认字符集,修改配置文件server.xml
                > 在server.xml的Connector标签中(改端口号的那个标签)添加如下属性:
                    URIEncoding="utf-8"
                > 修改完配置文件以后,get请求的编码就不用再处理的,但是post请求还是老样子。

    > 响应编码
        - 响应是服务器发送给浏览器
        - 服务器 --> 浏览器
        - 服务器 编码
            > 指定服务器的编码字符集为UTF-8。
            > 指定response的字符集
                response.setCharacterEncoding("utf-8");
            > 虽然我们已经指定了response的字符集为utf-8,但是浏览器并不是用utf-8解码。
                浏览器默认使用gb2312解码的,所以依然乱码,只不过没有那么乱。

        - 浏览器 解码
            > 浏览器的解码字符集可以通过浏览器来设置(不靠谱)
            > 我们可以通过服务器来告诉浏览器,我们的内容的编码格式为utf-8
            > 我们可以通过一个响应头来告诉浏览器,内容的编码格式:
                Content-Type:text/html;charset=utf-8
            > 通过response的方法,来设置响应头:
                response.setHeader("Content-Type", "text/html;charset=utf-8");

        解决方案:
            1.设置响应头
                response.setHeader("Content-Type", "text/html;charset=utf-8");
            2.设置response的编码格式
                response.setCharacterEncoding("utf-8");

            > 当我们设置Content-Type这个响应头时,服务器会自动使用响应头中的字符集为内容编码。

            > 最终方案:
                response.setContentType("text/html;charset=utf-8");

总结: post请求: - 在request.getParameter()方法第一次调用之前,调用如下代码: request.setCharacterEncoding("utf-8"); get请求: - 修改server.xml配置文件

<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
         响应:
            - 设置一个Content-Type响应头
                response.setContentType("text/html;charset=utf-8");

路径问题

    > URI和URL
        - URL是URI的一种实现,也是URI最常见的实现方式。
        - URI有两种实现方式URL和URN,URN用的很少
        - 我们说URL和URI实际上可以理解为一个意思

    > URL地址的格式
        http://主机名:端口号/项目名/资源路径/资源名

    ①相对路径和绝对路径
        > 相对路径
        - 之前我们使用的路径全都是相对路径:
            - 所谓的相对路径指相对于当前资源所在路径:
                http://主机名:端口号/项目名/资源路径/
        - 由于转发的出现,相对路径会经常发生变化,容易出现错误的链接
            所以在开发中我们一般不使用相对路径,而是使用绝对路径。

        > 绝对路径
        - 绝对路径使用/开头   
        - 由浏览器解析的绝对路径中的/代表的是服务器的根目录:
            http://主机名:端口号/
            注意:需要加上项目名

        - 由服务器解析的绝对路径中的/代表的项目的根目录:
            http://主机名:端口号/项目名/
            注意:不要加项目名

        - 转发的路径由服务器解析,设置绝对路径时不需要加项目名
        - 重定向的路径由浏览器解析,设置绝对路径时需要加上项目名


    ②常见的路径:
        url-pattern:
        转发的路径:
            - url-pattern和转发中的路径都是由服务器解析的,
                根目录是项目的根目录:
                    http://主机名:端口号/项目名/
            - 所以这两个路径不需要加项目名

        重定向的路径:
        页面中的路径:
            - 重定向和页面中的路径(HTML标签中的路径),由浏览器解析的,
                根目录是服务器的根目录:
                    http://主机名:端口号/
            - 所以这个两个路径必须加上项目名

(拓展)浅析Servlet执行原理

在JavaWeb学习研究中,Servlet扮演重要的作用,学好它,是后续JavaWeb学习的良好基础。无论是SSH,还是SSM,微服务JavaWeb技术,都应先学好Servlet,从而达到事半功倍的效果,本篇将主要分析Servlet的运行原理。

一、 UML

下图为Servlet UML关系图。

从图中,可以看出:

  1. 抽象类HttpServlet继承抽象类GenericServlet,其有两个比较关键的方法,doGet()和doPost()
  2. GenericServlet实现接口Servlet,ServletConfig,Serializable
  3. MyServlet(用户自定义Servlet类)继承HttpServlet,重写抽象类HttpServlet的doGet()和doPost()方法

注:任何一个用户自定义Servlet,只需重写抽象类HttpServlet的doPost()和doGet()即可,如上图的MyServlet

二、 Servlet在容器中的执行过程

Servlet只有放在容器中,方可执行,且Servlet容器种类较多,如Tomcat,WebLogic等。下图为简单的 请求响应 模型。

分析:

  1. 浏览器向服务器发出GET请求(请求服务器ServletA)
  2. 服务器上的容器逻辑接收到该url,根据该url判断为Servlet请求,此时容器逻辑将产生两个对象:请求对象(HttpServletRequest)和响应对象(HttpServletResponce)
  3. 容器逻辑根据url找到目标Servlet(本示例目标Servlet为ServletA),且创建一个线程A
  4. 容器逻辑将刚才创建的请求对象和响应对象传递给线程A
  5. 容器逻辑调用Servlet的service()方法
  6. service()方法根据请求类型(本示例为GET请求)调用doGet()(本示例调用doGet())或doPost()方法
  7. doGet()执行完后,将结果返回给容器逻辑
  8. 线程A被销毁或被放在线程池中

注意:

  1. 在容器中的每个Servlet原则上只有一个实例
  2. 每个请求对应一个线程
  3. 多个线程可作用于同一个Servlet(这是造成Servlet线程不安全的根本原因)
  4. 每个线程一旦执行完任务,就被销毁或放在线程池中等待回收

三、 Servlet在JavaWeb中扮演的角色

Servlet在JavaWeb中,扮演两个角色:页面角色和控制器角色。

有了jsp等动态页面技术后,Servlet更侧重于控制器角色,jsp+servlert+model 形成基本的三层架构

(一)页面Page角色

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out=response.getWriter();
        out.println("Hello!Servlet.");
    }

(二)控制器角色

jsp充当页面角色,Servlet扮演控制器角色,两者组合构建基本的MVC三层架构模式

四 、Servlet在容器中的生命周期

下图为Servlet生命周期简要概图

分析:

第一步:容器先加载Servlet类

第二步:容器实例化Servlet(Servlet无参构造函数执行)

第三步:执行init()方法(在Servlet生命周期中,只执行一次,且在service()方法执行前执行)

第四步:执行service()方法,处理客户请求,doPost()或doGet()

第五步:执行destroy(),销毁线程

如果文章有错的地方欢迎指正,大家在评论区互相交流。

相关推荐

jQuery VS AngularJS 你更钟爱哪个?

在这一次的Web开发教程中,我会尽力解答有关于jQuery和AngularJS的两个非常常见的问题,即jQuery和AngularJS之间的区别是什么?也就是说jQueryVSAngularJS?...

Jquery实时校验,指定长度的「负小数」,小数位未满末尾补0

在可以输入【负小数】的输入框获取到焦点时,移除千位分隔符,在输入数据时,实时校验输入内容是否正确,失去焦点后,添加千位分隔符格式化数字。同时小数位未满时末尾补0。HTML代码...

如何在pbootCMS前台调用自定义表单?pbootCMS自定义调用代码示例

要在pbootCMS前台调用自定义表单,您需要在后台创建表单并为其添加字段,然后在前台模板文件中添加相关代码,如提交按钮和表单验证代码。您还可以自定义表单数据的存储位置、添加文件上传字段、日期选择器、...

编程技巧:Jquery实时验证,指定长度的「负小数」

为了保障【负小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【负小数】的方法。HTML代码<inputtype="text"class="forc...

一篇文章带你用jquery mobile设计颜色拾取器

【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...

编程技巧:Jquery实时验证,指定长度的「正小数」

为了保障【正小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【正小数】的方法。HTML做成方法<inputtype="text"class="fo...

jquery.validate检查数组全部验证

问题:html中有多个name[],每个参数都要进行验证是否为空,这个时候直接用required:true话,不能全部验证,只要这个数组中有一个有值就可以通过的。解决方法使用addmethod...

Vue进阶(幺叁肆):npm查看包版本信息

第一种方式npmviewjqueryversions这种方式可以查看npm服务器上所有的...

layui中使用lay-verify进行条件校验

一、layui的校验很简单,主要有以下步骤:1.在form表单内加上class="layui-form"2.在提交按钮上加上lay-submit3.在想要校验的标签,加上lay-...

jQuery是什么?如何使用? jquery是什么功能组件

jQuery于2006年1月由JohnResig在BarCampNYC首次发布。它目前由TimmyWilson领导,并由一组开发人员维护。jQuery是一个JavaScript库,它简化了客户...

django框架的表单form的理解和用法-9

表单呈现...

jquery对上传文件的检测判断 jquery实现文件上传

总体思路:在前端使用jquery对上传文件做部分初步的判断,验证通过的文件利用ajaxFileUpload上传到服务器端,并将文件的存储路径保存到数据库。<asp:FileUploadI...

Nodejs之MEAN栈开发(四)-- form验证及图片上传

这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能。开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/R...

大数据开发基础之JAVA jquery 大数据java实战

上一篇我们讲解了JAVAscript的基础知识、特点及基本语法以及组成及基本用途,本期就给大家带来了JAVAweb的第二个知识点jquery,大数据开发基础之JAVAjquery,这是本篇文章的主要...

推荐四个开源的jQuery可视化表单设计器

jquery开源在线表单拖拉设计器formBuilder(推荐)jQueryformBuilder是一个开源的WEB在线html表单设计器,开发人员可以通过拖拉实现一个可视化的表单。支持表单常用控件...

取消回复欢迎 发表评论: