Servlet 详解

转载自博客园:https://www.cnblogs.com/whgk/p/6399262.html
以及菜鸟教程:https://www.runoob.com/servlet/servlet-life-cycle.html

一、什么是servlet?

    处理请求和发送响应的过程是由一种叫做Servlet的程序来完成的,并且Servlet是为了解决实现动态页面而衍生的东西。理解这个的前提是了解一些http协议的东西,并且知道B/S模式(浏览器/服务器)。

    B/S:浏览器/服务器。 浏览器通过网址来访问服务器,比如访问百度,在浏览器中输入 www.baidu.com,这个时候浏览器就会显示百度的首页,那么这个具体的过程,步骤是怎样的呢?这个就了解一下http请求和响应了。
在这里插入图片描述
    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

    使用 Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

下图显示了 Servlet 在 Web 应用程序中的位置
在这里插入图片描述

二、tomcat和servlet的关系

     Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户.而Servlet是一种运行在支持Java语言的服务器上的组件. Servlet最常见的用途是扩展Java Web服务器功能,提供非常安全的,可移植的,易于使用的CGI替代品.

    从http协议中的请求和响应可以得知,浏览器发出的请求是一个请求文本,而浏览器接收到的也应该是一个响应文本。但是在上面这个图中,并不知道是如何转变的,只知道浏览器发送过来的请求也就是request,我们响应回去的就用response。忽略了其中的细节,现在就来探究一下。
在这里插入图片描述
    ①:Tomcat将http请求文本接收并解析,然后封装成HttpServletRequest类型的request对象,所有的HTTP头数据读可以通过request对象调用对应的方法查询到

    ②:Tomcat同时会把要响应的信息封装为HttpServletResponse类型的response对象,通过设置response属性就可以控制要输出到浏览器的内容,然后将response交给tomcat,tomcat就会将其变成响应文本的格式返回给浏览器。

     Java Servlet API 是Servlet容器(tomcat)和servlet之间的接口,它定义了serlvet的各种方法,还定义了Servlet容器传送给Servlet的对象类,其中最重要的就是ServletRequest和ServletResponse。所以说我们在编写servlet时,需要实现Servlet接口,按照其规范进行操作。


三、编写Servlet

    1、创建一个HelloWorld 继承HttpServlet,重写doGet或者doPost方法,也就是看请求的方式是get还是post,然后用不同的处理方式来处理请求,

// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

// 扩展 HttpServlet 类
public class HelloWorld extends HttpServlet {
 
  private String message;

  public void init() throws ServletException
  {
      // 执行必需的初始化
      message = "Hello World";
  }

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
            throws ServletException, IOException
  {
      // 设置响应内容类型
      response.setContentType("text/html");

      // 实际的逻辑是在这里
      PrintWriter out = response.getWriter();
      out.println("<h1>" + message + "</h1>");
  }
  
  public void destroy()
  {
      // 什么也不做
  }
}

    2、在web.xml中配置HelloWorld,为什么需要配置?让浏览器发出的请求知道到达哪个servlet,也就是让tomcat将封装好的request找到对应的servlet让其使用。

<web-app>      
    <servlet>
        <servlet-name>HelloWorld</servlet-name> //servlet的名字
        <servlet-class>HelloWorld</servlet-class> // servlet的全限定名(包名+类名)
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloWorld</servlet-name> //servlet的名字
        <url-pattern>/HelloWorld</url-pattern> // 浏览器通过 "/HelloWorld"找到该servlet
    </servlet-mapping>
</web-app>  

    3、编译和部署Servlet
(1)先将servlet文件编译成能够直接使用的.class文件

javac HelloWorld.java

(2)再将生成的.class文件部署到web服务器相关目录下(这里使用tomcat)
    默认情况下,Servlet 应用程序 位于路径
< Tomcat-installation-directory >/webapps/ROOT 下,且 类文件 放在
< Tomcat-installation-directory>/webapps/ROOT/WEB-INF/classes 中。

    如果您有一个全限定名为 com.myorg.MyServlet 类,那么这个 Servlet 类必须位于 WEB-INF/classes/com/myorg/MyServlet.class 中。也就是说 类文件的目录必须和类的全限定名吻合

4、运行servlet
在浏览器中输入:http://localhost:8080/HelloWorld,
即可显示下列文字:
在这里插入图片描述


四、Servlet的原理

1、servlet的生命周期是什么?
    服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始化方法init(ServletConfig conf)

    该servlet对象去处理 所有客户端请求,在service(ServletRequest req,ServletResponse res)方法中执行。

    每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用与之对应的 doGet、doPost、doPut,doDelete 等方法。

    最后服务器关闭时,才会销毁这个servlet对象,执行destroy()方法。
在这里插入图片描述

五、Servlet其他细节

转自:https://blog.youkuaiyun.com/qq_28483283/article/details/51220749
不要在Servlet中创建成员!创建局部变量即可!
可以创建无状态成员!
可以创建有状态的成员,但状态必须为只读的!

1.Servlet与线程安全
    因为一个类型的Servlet只有一个实例对象,那么就有可能会现一个Servlet同时处理多个请求,那么Servlet是否为线程安全的呢?答案是:“不是线程安全的”。这说明Servlet的工作效率很高,但也存在线程安全问题!
所以我们 不应该在Servlet中创建成员变量,因为可能会存在一个线程对这个成员变量进行写操作,另一个线程对这个成员变量进行读操作。

2.让服务器在启动时就创建Servlet
    默认情况下,服务器会在某个Servlet第一次收到请求时创建它。也可以在web.xml中对Servlet进行配置,使服务器启动时就创建Servlet。

    <servlet>
        <servlet-name>hello1</servlet-name>
        <servlet-class>cn.itcast.servlet.Hello1Servlet</servlet-class>
        <load-on-startup>0</load-on-startup>[在<servlet>中配置<load-on-startup>,其中给出一个非负整数!]
    </servlet>
    <servlet-mapping>
        <servlet-name>hello1</servlet-name>
        <url-pattern>/hello1</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>hello2</servlet-name>
        <servlet-class>cn.itcast.servlet.Hello2Servlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello2</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>hello3</servlet-name>
        <servlet-class>cn.itcast.servlet.Hello3Servlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello3</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>

在元素中配置元素可以让服务器在启动时就创建该Servlet,其中元素的值必须是大于等于的整数,它的使用是服务器启动时创建Servlet的顺序。上例中,根据的值可以得知服务器创建Servlet的顺序为Hello1Servlet、Hello2Servlet、Hello3Servlet。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值