Servlet详解(一)

Servlet是什么?

Sun公司提供了Servlet这种技术供我们使用,Servlet(Server Applet 运行在服务端的小程序)是一个接口,定义了规范,我们需要去实现这个接口,然后由Tomcat服务器创建并且调用,运行在服务器端。

Servlet接口定义的是一套处理网络请求的规范,所有实现servlet的类,都需要实现它的五个方法,其中最主要init()、service()、destroy()三个方法,也就是说,所有实现servlet接口的类,或者说,所有想要处理网络请求的类,都需要执行这三个步骤!


Servlet工作机制

img

img


Tomcat架构

img

  • server层代表整个servlet容器,用于启动与监听服务端事件

  • service是由一个engine和一个或多个connector组成,这些connector共享一个Engine来处理请求

  • connector将在某个指定端口监听客户的请求,把从socket传送来的数据封装成request传递给Engine,并从Engine处获得响应返回给客户。

    • Tomcat通常会用到两种Connector:
      • Http Connector 在端口8080处侦听来自客户browser的http请求。
      • AJP Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求。
  • Engine负责处理来自相关联的service的所有请求,处理后返回给service,connector作为两者中间媒介出现,engine下可以配置多个虚拟主机,当engine获得一个请求时将这个请求匹配给对应的虚拟主机上处理

  • Host虚拟主机与某个网络域名(domain name)相匹配。一个主机下可以部署一个或者多个web应用,每个应用对应一个context,有一个context path。当host获得一个请求时将这个请求匹配到某个context上,将请求交给context处理,这种方法叫最长匹配。path==“”时即匹配所有无法匹配到context的请求。

  • context对应一个应用,由一个或多个servlet组成。context创建时将根据web.xml载入servlet类。

这是Tomcat的架构,然后介绍Tomcat是怎样启动的。对于engine, host, context来说,它们都属于容器,当接收到客户端请求的时候,请求会被传递到容器中,在一个容器中处理完毕之后,会被传递给下一个容器处理。因此,我们可以这样理解tomcat,总的来说,tomcat就是一种自上而下,一个容器里面又嵌套包含了另一个子容器的结构。所以,在tomcat启动的时候,我们也可以想象,它必定要先启动父容器,然后再启动子容器,在启动每一层容器的时候,还会启动容器中的一些相关组件,当所有的容器与组件都安装启动完毕,那么tomcat就启动完毕了~~


编写Servlet程序

public class Demo1 implements Servlet {
    @Override
    public void init(ServletConfig config) throw ServletException {
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException{
        System.out.println("service...");
    }
    @Override
    public ServletInfo getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
    }
    
}

可以知道有5个方法需要重写:init【初始化】、destroy【销毁】、service【服务】、getServletConfig【Servlet配置】、getServletInfo【Servlet信息】

Tomcat已经帮我们完成复杂的操作了,这样就不需要我们来写底层TCP连接了,Tomcat给我们返回三个对象:ServletConfig、ServletRequest、ServletResponse:

  • ServletConfig:

    • 通过反射,将web.xml文件中的<init-param></init-param>中的数据打包成ServletConfig对象了

      img

  • ServletRequest:

    • 将浏览器发送过来的请求报文封装为ServletRequest对象,我们可以使用他的方法来获取报文信息
  • ServletResponse:

    • Tomcat将ServletResponse对象传给Servlet对象时,是空的对象,经过Servlet逻辑处理后得到结果,最终通过response.write()方法,将结果写入response内部的缓冲区。Tomcat会在servlet处理结束后,拿到response,遍历里面的信息,组装成HTTP响应发给客户端。

      img


配置Servlet

要想让Tomcat能创建该Servlet对象,需要再在web.xml文件中,配置如下代码,使得Tomcat服务器可以找到这个Servlet类且创建它(Servlet3.0支持使用注解@WebServlet来配置)

<servlet>
    <!-- 为Servlet起一个名字(一般是和类名是一样的) -->
    <servlet-name>MyServlet</servlet-name>
    <!-- 类的存储具体位置,要写上包名 -->
    <servlet-class>top.linzeliang.servlet.MyServlet</servlet-class>
</servlet>

<!-- 配置Demo1的映射路径 -->
<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <!-- 外界通过访问MyServlet的资源路径 -->
    <url-pattern>/MyServlet(这是资源路径,不是虚拟目录)</url-pattern>
</servlet-mapping>

同一个Servlet可以被映射到多个URL上:

<servlet>
  <servlet-name>MyServlet</servlet-name>
  <servlet-class>top.linzeliang.servlet.MyServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>MyServlet</servlet-name>
  <url-pattern>/MyServlet1</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>MyServlet</servlet-name>
  <url-pattern>/MyServlet2</url-pattern>
</servlet-mapping>

无论是使用/MyServlet1资源路径还是/MyServlet2资源路径,都会创建Demo1的实例

执行原理:

  1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
  2. 查找web.xml文件中的<url-pattern>标签体内容是否与请求的资源路径相同
  3. 如果有,则通过servlet-name在找到对应的<servlet-class>全类名(src目录下的)
  4. tomcat会将字节码文件加载进内存,并且创建该Servlet的实例
  5. 然后开始调用Servlet对象的方法

使用Servlet3.0注解@WebServlet来配置Servlet

// WebServlet注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {

    //相当于<Servlet-name>
    String name() default "";

    //代表urlPatterns()属性配置
    String[] value() default {};

    //相当于<url-pattern>
    String[] urlPatterns() default {};

    //相当于<load-on-startup>
    int loadOnStartup() default -1;

    WebInitParam[] initParams() default {};

    boolean asyncSupported() default false;

    String smallIcon() default "";

    String largeIcon() default "";

    String description() default "";

    String displayName() default "";
}
  • @WebServlet

    • @WebServlet(urlPatterns="/资源路径") 直接在这里写资源路径即可,因为资源路径是最重要的,所以如果只有一个值的话不需要写参数名
    • @WebServlet({"/资源路径1", “/资源路径2”, “/资源路径3”}) 一个Servlet可以定义多个访问路径
    • 路径定义规则:
      • /xxx:路径匹配
        • /* 代表通配符,任何资源路径都可以访问该Servlet
      • /xxx/xxx:多重路径匹配
      • *.do:扩展名匹配
  • 如果*.扩展名正斜杠(/)开头并以“/*”结尾两种通配符同时出现,匹配的是哪一个?

    • 看谁的匹配度高,谁就被选择

    • *.扩展名的优先级最低

  • Servlet映射的URL可以使用通配符和Servlet可以被映射到多个URL上的作用

    • 隐藏网站是用什么编程语言写的【.php,.net,.asp实际上访问的都是同一个资源】

    • 用特定的后缀声明版权【公司缩写】:

      <servlet>
        <servlet-name>Demo1</servlet-name>
        <servlet-class>top.linzeliangtop.web.Demo1</servlet-class>
      </servlet>
      
      <servlet-mapping>
        <servlet-name>Demo1</servlet-name>
        <url-pattern>*.jsp</url-pattern>
      </servlet-mapping>
      
      <servlet-mapping>
        <servlet-name>Demo1</servlet-name>
        <url-pattern>*.net</url-pattern>
      </servlet-mapping>
      
      <servlet-mapping>
        <servlet-name>Demo1</servlet-name>
        <url-pattern>*.asp</url-pattern>
      </servlet-mapping>
      
      <servlet-mapping>
        <servlet-name>Demo1</servlet-name>
        <url-pattern>*.php</url-pattern>
      </servlet-mapping>
      

Servlet继承体系结构

继承HttpServlet编写Servlet程序

一般我们开发时候,都是继承HttpServlet抽象类,而不是去实现Servlet接口。然后,一般重写doGet和doPost方法(其他的doXxx方法不常用)


Servlet生命周期

  1. 加载Servlet,Tomcat在第一次访问时创建Servlet实例
  2. 当Servlet实例被创建后,Tomcat会调用init方法来初始化对象(init()方法只在创建对象后调用一次)
  3. 然后Tomcat调用Servlet中的service()方法来处理浏览器的请求
  4. 当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法(destroy()方法先调用,再销毁Servlet对象),释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁。
  5. 最后Servlet对象被回收
  • Servlet的init方法:
    • 只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的。当多个用户同时访问时,可能存在线程安全问题。所以尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值
  • Servlet对象的创建时机(在<servlet>标签下配置):
    1. 第一次被访问时,创建(默认情况下,第一次被访问时,Servlet被创建)
      * <load-on-startup>的值为负整数,可以为-1
    2. 在服务器启动时,创建
      • <load-on-startup>的值为0或正整数

HTTP基础

  • 什么是HTTPHyper Text Transfer Protocol 超文本传输协议
    • 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
    • 特点:
      1. 基于TCP/IP的高级协议
      2. 默认端口号:80
      3. 基于请求/响应模型的:一次请求对应一次响应
      4. 无状态的:每次请求之间相互独立,不能交互数据
    • 历史版本:
      • 1.0:每一次请求响应都会建立新的连接
      • 1.1:复用连接
  • 请求消息数据格式
    1. 请求行
      请求方式 请求url 请求协议/版本
      GET /login.html HTTP/1.1

      • 请求方式:
        • HTTP协议有7中请求方式,常用的有2种
          • GET:
            1. 请求参数在请求行中,在url后。
            2. 请求的url长度有限制的
            3. 不太安全
          • POST:
            1. 请求参数在请求体中
            2. 请求的url长度没有限制的
            3. 相对安全
    2. 请求头:客户端浏览器告诉服务器一些信息
      请求头名称: 请求头值

      • 常见的请求头:
        1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息

          • 可以在服务器端获取该头的信息,解决浏览器的兼容性问题
        2. Referer:http://localhost/login.html

          • 告诉服务器,我(当前请求)从哪里来?
            • 作用:
              1. 防盗链:
              2. 统计工作:
    3. 请求空行
      空行,就是用于分割POST请求的请求头,和请求体的。

    4. 请求体(正文):

      • 封装POST请求消息的请求参数的
      • 字符串格式:
        POST /login.html HTTP/1.1
        Host: localhost
        User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
        Accept-Encoding: gzip, deflate
        Referer: http://localhost/login.html
        Connection: keep-alive
        Upgrade-Insecure-Requests: 1


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Servlet 是 Java Web 开发中最基础的组件之一,其主要作用是处理客户端(浏览器)发出的 HTTP 请求并返回响应结果。在 Servlet 中,有一些常用的方法,下面对这些方法进行详细介绍。 1. `init()` 方法 `init()` 方法是 Servlet 的生命周期方法之一,表示 Servlet 初始化时调用的方法。在 Servlet 对象被创建后,容器会自动调用 `init()` 方法,用来对 Servlet 进行初始化,例如读取配置文件、建立数据库连接等。`init()` 方法只会被调用一次。 2. `service()` 方法 `service()` 方法是 Servlet 的核心方法,用来处理客户端发送的请求并生成响应结果。在每次客户端请求时,容器都会调用 `service()` 方法,将请求信息封装为一个 `ServletRequest` 对象和一个 `ServletResponse` 对象,然后调用具体的 `doXXX()` 方法(如 `doGet()`、`doPost()` 等)来处理请求。 3. `destroy()` 方法 `destroy()` 方法也是 Servlet 的生命周期方法之一,表示 Servlet 被销毁时调用的方法。在 Servlet 对象被销毁前,容器会自动调用 `destroy()` 方法,用来释放资源、关闭数据库连接等。`destroy()` 方法只会被调用一次。 4. `doGet()` 方法 `doGet()` 方法是处理 HTTP GET 请求的方法。当客户端发送 GET 请求时,容器会自动调用 `doGet()` 方法,并将请求信息封装为一个 `HttpServletRequest` 对象和一个 `HttpServletResponse` 对象,然后在此方法中编写处理逻辑,并通过 `HttpServletResponse` 对象生成响应结果。 5. `doPost()` 方法 `doPost()` 方法是处理 HTTP POST 请求的方法。当客户端发送 POST 请求时,容器会自动调用 `doPost()` 方法,并将请求信息封装为一个 `HttpServletRequest` 对象和一个 `HttpServletResponse` 对象,然后在此方法中编写处理逻辑,并通过 `HttpServletResponse` 对象生成响应结果。 6. `doPut()` 方法 `doPut()` 方法是处理 HTTP PUT 请求的方法。当客户端发送 PUT 请求时,容器会自动调用 `doPut()` 方法,并将请求信息封装为一个 `HttpServletRequest` 对象和一个 `HttpServletResponse` 对象,然后在此方法中编写处理逻辑,并通过 `HttpServletResponse` 对象生成响应结果。 7. `doDelete()` 方法 `doDelete()` 方法是处理 HTTP DELETE 请求的方法。当客户端发送 DELETE 请求时,容器会自动调用 `doDelete()` 方法,并将请求信息封装为一个 `HttpServletRequest` 对象和一个 `HttpServletResponse` 对象,然后在此方法中编写处理逻辑,并通过 `HttpServletResponse` 对象生成响应结果。 以上是 Servlet 中常用的方法,了解这些方法可以帮助我们更好地理解 Servlet 的工作原理,并能够编写出符合规范的 Servlet 程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值