Servlet

  • 一、Servlet 执行原理
  • 二、生命周期
    • 2.1 生命周期方法
    • 2.2 load-on-startup 参数
  • 三、HttpServlet
  • 四、配置方式
    • 4.1 url-pattern 匹配规则
    • 4.2 web.xml配置
    • 4.3 注解配置

一、Servlet 原理

Servlet_第1张图片
如上图:浏览器通过url访问服务器端,此时服务器端的service() 方法就会执行。

执行原理:

  1. 当服务器接收到客户端浏览器的请求后,会解析请求的url路径,获取访问的servlet的资源路径/demo1;
  2. 查找web.xml文件,是否有对应的标签体内容与资源内容一致;
  3. 如果有 标签体内容,则在找到对应的全类名
  4. tomcat会根据全类名,将字节码文件加载进内存,创建其对象
  5. 调用其方法

二、生命周期

2.1 生命周期方法

1、被创建:执行init方法,只执行一次。
说明:该方法执行后,就会创建Servlet对象,并且我们也可以在该方法中加载资源。

那么什么时候才会调用init方法,创建Servlet对象呢??
① 默认情况下第一次访问该类时,Servlet被创建;
② 我们也可以根据自己的需求,配置指定Servlet创建时机。

配置方式,在标签下配置如下参数:

  1. 第一次被访问时,创建servlet。
// 默认值就是 -1
<load-on-startup>-1load-on-startup>
  1. 在服务器启动时,创建servlet
// 设置值0或者正整数
<load-on-startup>1load-on-startup>

注意:
Servlet的init方法只执行一次,说明内存中只存在一个Servlet对象,Servlet是单例。
问题:多个用户同时访问时,可能存在线程安全问题。
解决线程安全问题:尽量不要再Servlet中定义成员变量。即使定义了成员变量,也不要对齐修改值。

2、提供服务:执行service方法,执行多次。每次访问Servlet时,都会被执行。

3、被销毁:执行destory方法,只执行一次
说明:在服务器正常关闭时执行,执行一次。
在Servlet被销毁之前执行,一般用于释放资源。

创建一个类,被实现Servlet接口中的方法。

public class Demo2_servlet implements Servlet {
    /**
     * @description: 初始化方法,在servlet被创建时执行。只会执行一次。
     * @param servletConfig
     * @return: void
     * @author: King
     * @date: 2019-03-12 13:59
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init.........");
    }

    /**
     * @description: 获取servlet的配置对象 ServletConfig
     * @param
     * @return: javax.servlet.ServletConfig
     * @author: King
     * @date: 2019-03-12 14:08
     */
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * @description: 提供服务的方法,每一次servlet被访问时都会执行。
     * @param servletRequest
     * @param servletResponse
     * @return: void
     * @author: King
     * @date: 2019-03-12 14:00
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service.........");
    }

    /**
     * @description: 获取servlet一些信息,例如版本、作者等。
     * @param
     * @return: java.lang.String
     * @author: King
     * @date: 2019-03-12 14:09
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * @description: 销毁。在服务器正常关闭时执行,执行一次。
     * @param
     * @return: void
     * @author: King
     * @date: 2019-03-12 14:01
     */
    @Override
    public void destroy() {
        System.out.println("destroy.........");
    }
}

2.2 load-on-startup 参数

load-on-startup标记容器是否在启动的时候实例化并调用其init()方法的优先级。

它的值表示servlet应该被载入的顺序

  • 当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
  • 如果值小于0或未指定时,则表示只有在第一次请求的容器才在该servlet调用初始化函数
  • 正值越小,servlet的优先级越高,应用启动时就越先加载。
  • 值相同时,容器就会自己选择顺序来加载。

三、HttpServlet

HttpServlet:对http协议的封装
定义类继承HttpServlet,重写doGet/doPost等其他请求方法,然后做出逻辑判断。如下代码:

@WebServlet("/demo3")
public class Demo3_Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet....");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost....");
    }
}

四、配置方式

4.1 url-pattern 匹配规则

url-pattern :表示Servlet资源访问路径
一个Servlet可以定义多个访问路径

方式一:精准匹配

以“/”开头,以字母(非”*”)结束。比如:单层路径/xxx、多层路径/xxx/xxx

比如:

<servlet-mapping>
    <servlet-name>myServletservlet-name>
    <url-pattern>/demo.htmlurl-pattern>
    <url-pattern>/demo1url-pattern>
    <url-pattern>/user/accounturl-pattern>
servlet-mapping>

当访问http://localhost:8080/demo.htmlhttp://localhost:8080/demo1http://localhost:8080/user/account路径时,都可以访问该myServlet。

方式二:扩展名匹配

以* 开头,以扩展名结束。比如:*.do*.jsp等等。

<servlet-mapping>
    <servlet-name>myServletservlet-name>
    <url-pattern>*.dourl-pattern>
    <url-pattern>*.jspurl-pattern>
    <url-pattern>*.htmlurl-pattern>
servlet-mapping>

当访问http://localhost:8080/findAll.dohttp://localhost:8080/index.jsphttp://localhost:8080/login.html路径时,都可以访问该myServlet。

方式三:匹配最长路径

匹配范围:可以匹配所有请求,包括静态资源。
分析:tomcat会将所有的请求全部交由对应的Servlet进行处理,最终都会在这个Servlet中结束。也就是说,如果我们访问.jsp等静态页面,也会被Servlet拦截,从而导致无法访问该静态页面。

以 / 开头,并以 * 结尾,即/*

<servlet-mapping>
    <servlet-name>myServletservlet-name>
    <url-pattern>/*url-pattern>
servlet-mapping>

当访问http://localhost:8080/xxx.dohttp://localhost:8080/xxx.jsphttp://localhost:8080/xxx.html路径时,都可以访问该myServlet。

方式四:缺省匹配

会拦截除jsp的所有请求,交由Servlet处理。但不会拦截jsp。

/:默认匹配

<servlet-mapping>
    <servlet-name>myServletservlet-name>
    <url-pattern>/url-pattern>
servlet-mapping>

如上,当我们访问http://localhost:8080/test.jsp时,不会被Servlet拦截,而是直接访问test.jsp。

为什么不会拦截jsp文件?
因为tomcat做了如下配置
tomcat默认配置/conf/web.xml:

<servlet-mapping>
    <servlet-name>defaultservlet-name>
    <url-pattern>/url-pattern>
servlet-mapping>


<servlet-mapping>
    <servlet-name>jspservlet-name>
    <url-pattern>*.jspurl-pattern>
    <url-pattern>*.jspxurl-pattern>
servlet-mapping>

当访问http://localhost:8080/随意输入,都可以访问该myServlet。

注意:被该注解修饰的Servlet被访问的优先级很低,只有在找不到【输入的路径对应的Servlet】时,才会访问该Servlet。

优先顺序

当一个url与多个servlet的匹配规则可以匹配时,则按照 精确路径 > 最长路径 > 扩展名 > 缺省匹配 这样的优先级匹配到对应的servlet。

引申

在SpringMVC的web.xml中如下配置时:

  
  <servlet>
    <servlet-name>dispatcherServletservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:springmvc.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServletservlet-name>
    
    <url-pattern>/url-pattern>
  servlet-mapping>

/* : 如果访问路径中有 .jsp,那么该访问会被 SpringMVC 的 DispatcherServlet 处理,当做一个 Controller 去匹配,匹配不到就会返回404。
/ : 如果访问路径中有.jsp,将直接jsp,不经过 SpringMVC 的 DispatcherServlet ,不会被他拦截。

4.2 使用web.xml配置

web.xml


<servlet>
    <servlet-name>demo1servlet-name>
    <servlet-class>cn.king.web.servlet.Demo1_servletservlet-class>
servlet>

<servlet-mapping>
    <servlet-name>demo1servlet-name>
    
    <url-pattern>/demo1url-pattern>
    <url-pattern>/demo2url-pattern>
servlet-mapping>

4.3 注解配置

版本要求:Servlet 3.0及其以后的版本

我们可以不在web.xml中配置项目的访问路径、资源路径,我们可以采用更简便的方式:注解,来配置。
使用方式:
在类上使用@WebServlet注解,进行配置。
例如:
匹配单一路径、匹配多个路径

@WebServlet("/demo") 匹配单一路径
@WebServlet({"/demo4","/d4","/dm4"}) 匹配多个路径
public class ServletDemo implements Servlet {}

你可能感兴趣的:(JavaWeb)