8、快速入门Servlet

目录

1、web概述

1.1、Web与JavaWeb的概念

1.2、JavaWeb技术栈

1.2.1、B/S架构

1.2.2 静态资源

1.2.3 动态资源

1.2.4 数据库

1.2.5 HTTP协议

1.2.6 Web服务器

1.3、web核心

2、HTTP

2.1、简述

2.2、请求数据格式

2.2.1、格式介绍

2.2、响应数据格式

2.2.1、格式介绍

2.2.2、响应状态码

4、Servlet

4.1、简介

4.2、Servelt快速入门

快速创建一个Servlet

 4.3、执行流程

4.4、生命周期

4.5、方法介绍

4.6 体系结构

4.7、urlPattern配置

4.8、XML配置


前导

1、web概述

1.1、Web与JavaWeb的概念

Web:全球广域网 ,也称为万维网(www),能够通过浏览器访问的网站

JavaWeb:是用Java技术来解决相关web互联网领域的技术栈       

1.2、JavaWeb技术栈

了解JavaWeb技术栈之前,有一个很重要的概念要介绍。

1.2.1、B/S架构

B/S 架构:Browser/Server,浏览器/服务器 架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可。大家可以通过下面这张图来回想下我们平常的上网过程:

1.2.2 静态资源

静态资源主要包含HTML、CSS、JavaScript、图片等,主要负责页面的展示

1.2.3 动态资源

动态资源主要包含Servlet、JSP等,主要用来负责逻辑处理。

1.2.4 数据库

数据库主要负责存储数据。

1.2.5 HTTP协议

HTTP协议:主要定义通信规则

1.2.6 Web服务器

Web服务器:负责解析 HTTP 协议,解析请求数据,并发送响应数据

1.3、web核心

2、HTTP

2.1、简述

HTTP的概念

HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则

HTTPt特点

1、基于TCP协议:面向连接,安全

        TCP是一种面向连接的(建立连接之前是需要经过三次握手)、可靠的、基于字节流的传输层通信协议,在数据传输方面更安全。

2、基于请求-响应模型:一次请求对应一次响应

        请求和响应是一一对应关系

3、HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求都是独立的

        无状态指的是客户端发送HTTP请求给服务端之后,服务端根据请求响应数据,响应完后,不会记录任何信息。这种特性有优点也有缺点

                        缺点:多次请求间不能共享数据(Java中使用会话技术(session、cookie)可以解决这个问题)

                        优点:速度快

2.2、请求数据格式

2.2.1、格式介绍

请求数据总共分为三部分内容,分别为 请求行、请求头、请求体

请求行: HTTP请求中的第一行数据,请求行包含三块内容,分别是

         GET[请求方式]

         /[请求URL路径]

         HTTP/1.1[HTTP协议及版本]

         请求方式有七种,最常用的是GET和POST

请求头: 第二行开始,格式为key: value形式

         请求头中会包含若干个属性,常见的HTTP请求头有:

Host: 表示请求的主机名
User-Agent: 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 ...Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT ...)like Gecko;
Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有;
Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。

请求体: POST请求的最后一部分,存储请求参数

GET和POST两个请求之间的区别:

        GET请求请求参数在请求行中,没有请求体,POST请求请求参数在请求体中

        GET请求请求参数大小有限制,POST没有

小结:

  1. 请求数据中包含三部分内容,分别是请求行、请求头和请求体

  2. POST请求数据在请求体中,GET请求数据在请求行上

2.2、响应数据格式

2.2.1、格式介绍

响应数据总共分为三部分内容,分别为 响应行、响应头、响应体

响应行: 响应数据 的第一行数据,响应行包含三块内容,分别是

         HTTP/1.1[HTTP协议及版本]

         200[响应状态码]

         ok[状态码的描述]

响应头: 第二行开始,格式为key: value形式

         响应头中会包含若干个属性,常见的HTTP响应头有:

Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;
Content-Length:表示该响应内容的长度(字节数);
Content-Encoding:表示该响应压缩算法,例如gzip;
Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒

响应体: 最后一部分。存放响应数据

        上图的<html>...</html>这部分就是响应体,响应体和响应头之间有一行空格隔开。

2.2.2、响应状态码

状态码大全https://cloud.tencent.com/developer/chapter/13553

状态码分类:

状态码分类 说明
1xx 响应中——临时状态码,表示请求已被接受,告诉客户端应该继续请求或者如果它已经完成则忽略它
2xx 成功——表示请求已经成功被接受,处理已经完成
3xx 重定向——重定向到其他地方;它让客户端在发起一个请求以完成整个处理
4xx 客户端错误——处理发生错误,责任在客户端,如:客户端请求一个不存在的资源,客户端未被授权,禁止访问等
5xx 服务端错误——处理发生错误,责任在服务端,如:服务器抛出异常,路由出错,HTTP版本不支持等

常见的响应状态码:

状态码 英文描述 解释
200

ok

客户端请求成功,即处理成功,这是我们最想看到的状态码
302 Found 指示所请求的资源已移动到由Location响应头给定的URL,浏览器会自动重新访问这个页面
304 Not Modified 告诉客户端,你请求的资源至上次获得后,服务端并未修改,你直接使用你本地缓存把。隐式重定向
400 Bad Request 客户端请求有语法错误,不能被服务器所理解
403 Forbidden 服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源
404 Not Found  请求资源不存在,一般是URL输入有误,或者网站资源被删除了
428 Procondition Request 服务器要求有条件的请求,告诉客户端要想访问该资源,必须携带特定的请求头
429 Too Many Requests 太多请求,可以限制客户端请求某个资源的数量,配合Retry-After(多长时间后可以请求)响应头一起使用
431 Request Header Fields Too Large 请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少头域的大小后重新提交。
405 Method Not Allowed 请求方式有误,比如应用GET请求方式的资源用来POST
500 Internal Server Error 服务器发生不可预期的错误。服务器出异常了,赶紧去看日志吧
503 Service Unavailable 服务器尚未准备好处理请求。服务器刚刚启动,还未初始化好
511 Network Authentication Required 客户端需要进行身份验证才能获得网络资源访问权限

小结

  1. 响应数据中包含三部分内容,分别是响应行、响应头和响应体

  2. 掌握200,404,500这三个响应状态码所代表含义,发布是成功、所访问资源不存在和服务的错误

4、Servlet

4.1、简介

Servelt是Java提供的一门动态web资源开发技术

Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。

使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同内容。

Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet

4.2、Servelt快速入门

1、创建web项目,导入Servlet依赖坐标

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope> 
<!--
      此处为什么需要添加该标签?
      provided指的是在编译和测试过程中有效,最后生成的war包时不会加入
       因为Tomcat的lib目录中已经有servlet-api这个jar包,如果在生成war包的时候生效就会和Tomcat中的jar包冲突,导致报错
    -->
</dependency>

2、创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话

import javax.servlet.*;
import java.io.IOException;

public class ServletDemo1 implements Servlet {

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello Servlet");
    }
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

3、配置:在类中使用@WebServlet注解,配置该Servlet的访问路径(还可以在web.xml配置访问路径)

@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {

.....
}

 4、访问:启动Tomcat,浏览器输入URL访问该Servlet

http://localhost:8080/web-demo/demo1

快速创建一个Servlet

具体操作如下:

 

确认一些信息,然后点击Finish 

 先后点击Apply > ok

先删除pom.xml中的一些无效wu'zuo'bia

在pom.xml导入相关坐标

    <dependencies>
        <!-- servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <!--tomcat插件-->
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin></plugins>
    </build>

 创建MyServlet类,实现Servlet接口,重写所有方法,在service()方法中输出hello Servlet

 在MyServlet类上添加@WebServlet注解,规定该Servlet的访问路径

 

 启动tomcat服务器后,在浏览器中输入http://localhost:8080/web-demo/demo1,在控制台看见 hello Servlet,则证明Servlet程序已经成功运行

 4.3、执行流程

我们并没有创建MyServlet类的对象,也没有调用对象中的service方法,为什么在控制台就打印了hello Servlet句话呢?

要想回答上述问题,我们就需要对Servlet的执行流程进行一个学习

浏览器发出 http://localhost:8080/web-demo/demo1请求,从请求中可以解析出三部分内容,分别是 localhost:8080、web-demo、demo1       

        根据localhost:8080 可以找到要访问的Tomcat Web服务器

        根据 web-demo 可以找到部署在Tomcat服务器上的web-demo项目

        根据demo1可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet注解后面的值进行匹配

找到MyServlet这个类后,Tomcat Web服务器就会为MyServlet这个类创建一个对象,然后调用对象中的service()方法

        MyServlet实现了Servlet接口,所以类中必然会重写service()方法供Tomcat Web服务器调用

        service方法中有ServletRequest和ServletResponse两个参数,ServletRequest封装的是请求数据,ServletResponse封装的是响应数据,后期我们可以这两个参数实现前后端的数据交互

小结

介绍完Servlet的执行流程,需要大家掌握两个问题:

1、Servlet由谁创建?Servlet方法由谁调用?

        Servlet由web服务器(Tomcat)创建,Servlet()方法由web服务器调用

2、服务器怎么知道Servlet中一定由service方法?

        因为我们自己定义的Servlet必须实现Servlet接口并重写其方法,而Servlet接口中有service()方法

4.4、生命周期

介绍完Servlet的执行流程后,我们知道Servlet是由Tomcat Web服务器帮我们创建的

接下来咱们再来思考一个问题:

        Tomcat什么时候创建的Servlet对象?

要想回答上述问题,我们就需要对Servlet的生命周期进行一个学习。

生命周期: 对象的生命周期指一个对象从被创建到被销毁的整个过程

Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:

1、加载和实例化:默认情况下,当Servlet被第一次访问时,由容器创建Servlet对象

默认情况Servlet会在第一次访问被容器创建,但是如果创建Servlet比较耗时的话,那么第一个访问的人等待的时间就比较长,用户的体验就比较差,那么我们能不能把Servlet的创建放到服务器启动的时候来创建,具体如何来配置?

@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
loadOnstartup的取值有两类情况
	(1)负整数:第一次访问时创建Servlet对象 (默认情况)
	(2)0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高

2、初始化:在Servlet实例化后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次

3、请求处理:每当请求Servlet时,容器就会调用Servlet对象的 service()方法对请求进行处理

4、服务终止:当需要释放内存或容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例(对象),该实例随后会被Java的垃圾收集器所回收

接下来演示以下Servlet的生命周期

package com.clear.web;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

/**
 * Servlet生命周期方法
 */
@WebServlet(urlPatterns = "/demo2", loadOnStartup = 1)
public class ServletDemo2 implements Servlet {

    /**
     * 初始化方法
     * 1.调用时机:默认情况下,Servlet被第一次访问时,调用
     * * loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用
     * 2.调用次数: 1次
     *
     * @param config
     * @throws ServletException
     */
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init...");
    }

    /**
     * 提供服务
     * 1.调用时机:每一次Servlet被访问时,调用
     * 2.调用次数: 多次
     *
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }

    /**
     * 销毁方法
     * 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
     * 2.调用次数: 1次
     */
    public void destroy() {
        System.out.println("destroy...");
    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public String getServletInfo() {
        return null;
    }


}

小结

1、Servlet对象在上面时候创建的?

        默认是在第一访问时创建的,可以使用@WebServlet(urlPatterns="/demo2",loadOnStartup=1)修改成服务器启动的时候创建

2、Servlet生命周期中涉及到的三个方法,这三个方法是什么?什么时候被调用?调用几次?

        涉及的三个方法分别是 init()、service()、destroy()

        init()方法在Servlet对象被创建时执行,只执行一次

        service()方法在Servlet对象被访问时调用,每访问一次就调用一次

        destroy()方法在Servlet对象被销毁或者是web服务器关闭时调用,只执行一次

4.5、方法介绍

Servlet接口中共有五个方法,前面已经提到了三个方法了,还剩下两个方法作用分别是什么?

接下来先回顾一下前三个方法,分别是:

初始化方法,在Serlvet被创建时执行,只执行一次

void init(ServletConfig config)

提供服务方法, 每次Servlet被访问,都会调用该方法

void service(ServletRequest req, ServletResponse res)

销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet

void destroy() 

剩下的两个方法是:

获取Servlet信息

String getServletInfo() 
//该方法用来返回Servlet的相关信息,没有什么太大的用处,一般我们返回一个空字符串即可
public String getServletInfo() {
    return "";
}

获取ServletConfig对象

ServletConfig getServletConfig()

ServletConfig对象,在init方法的参数中有,而Tomcat Web服务器在创建Servlet对象的时候会调用init方法,必定会传入一个ServletConfig对象,我们只需要将服务器传过来的ServletConfig进行返回即可。具体如何操作?

        可以提升init()方法的形参init(ServletConfig config)的作用域,然后在getServletConfig()方法中直接返回即可

package com.clear.web;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

/**
 * Servlet方法介绍
 */
@WebServlet(urlPatterns = "/demo3",loadOnStartup = 1)
public class ServletDemo3 implements Servlet {

    private ServletConfig servletConfig;
    /**
     *  初始化方法
     *  1.调用时机:默认情况下,Servlet被第一次访问时,调用
     *      * loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用
     *  2.调用次数: 1次
     * @param config
     * @throws ServletException
     */
    public void init(ServletConfig config) throws ServletException {
        this.servletConfig = config;
        System.out.println("init...");
    }
    public ServletConfig getServletConfig() {
        return servletConfig;
    }
    
    /**
     * 提供服务
     * 1.调用时机:每一次Servlet被访问时,调用
     * 2.调用次数: 多次
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("servlet hello world~");
    }

    /**
     * 销毁方法
     * 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
     * 2.调用次数: 1次
     */
    public void destroy() {
        System.out.println("destroy...");
    }
    
    public String getServletInfo() {
        return "";
    }
}

getServletInfo()和getServletConfig()这两个方法使用的不是很多,了解即可

4.6 体系结构

通过上面的学习,我们知道要想编写一个Servlet就必须要实现Servlet接口,重写接口中的5个方法,虽然已经能完成要求,但是编写起来还是比较麻烦的,因为我们更关注的其实只有service方法,那有没有更简单方式来创建Servlet呢?

要想解决上面的问题,我们需要先对Servlet的体系结构进行下了解:

因为我们将来开发B/S架构的web项目,都是针对HTTP协议,所以我们自定义Servlet,会通过继承

 HttpServlet来实现

package com.clear.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/demo4")
public class MyServletDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //TODO GET 请求方式处理逻辑
        System.out.println("get~~~");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //TODO Post 请求方式处理逻辑
        System.out.println("post~~~");
    }
}

要想发送一个GET请求,请求该Servlet,只需要通过浏览器发送http://localhost:8080/web-demo/demo4,就能看到doGet方法被执行了

此时控制台打印了 get~~~

 

 要想发送一个POST请求,请求该Servlet,单单通过浏览器是无法实现的,这个时候就需要编写一个form表单来发送请求,在webapp下创建一个a.html页面,内容如下:

 Servlet的简化编写就介绍完了,接着需要思考两个问题:

  1. HttpServlet中为什么要根据请求方式的不同,调用不同的方法?

  2. 如何调用?

针对问题一,我们需要回顾之前的知识点前端发送GET和POST请求的时候,参数的位置不一致GET请求参数在请求行中,POST请求参数在请求体中,为了能处理不同的请求方式,我们得在service方法中进行判断,然后写不同的业务处理,这样能实现,但是每个Servlet类中都将有相似的代码,针对这个问题,有什么可以优化的策略么?

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/demo5")
public class ServletDemo5 implements Servlet {

    public void init(ServletConfig config) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        //如何调用?
        //获取请求方式,根据不同的请求方式进行不同的业务处理
        HttpServletRequest request = (HttpServletRequest)req;
       //1. 获取请求方式
        String method = request.getMethod();
        //2. 判断
        if("GET".equals(method)){
            // get方式的处理逻辑
        }else if("POST".equals(method)){
            // post方式的处理逻辑
        }
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

要解决上述问题,我们可以对Servlet接口进行继承封装,来简化代码开发。

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class MyHttpServlet implements Servlet {
    public void init(ServletConfig config) throws ServletException {

    }

    public ServletConfig getServletConfig() {
        return null;
    }

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest)req;
        //1. 获取请求方式
        String method = request.getMethod();
        //2. 判断
        if("GET".equals(method)){
            // get方式的处理逻辑
            doGet(req,res);
        }else if("POST".equals(method)){
            // post方式的处理逻辑
            doPost(req,res);
        }
    }

    // 根据请求方式的不同,分别执行以下两个方法
    protected void doPost(ServletRequest req, ServletResponse res) {
    }

    protected void doGet(ServletRequest req, ServletResponse res) {
    }

    public String getServletInfo() {
        return null;
    }

    public void destroy() {

    }
}

有了MyHttpServlet这个类,以后我们再编写Servlet类的时候,只需要继承MyHttpServlet,重写父类中的doGet和doPost方法,就可以用来处理GET和POST请求的业务逻辑。接下来,可以把ServletDemo5代码进行改造

@WebServlet("/demo5")
public class ServletDemo5 extends MyHttpServlet {

    @Override
    protected void doGet(ServletRequest req, ServletResponse res) {
        System.out.println("get...");
    }

    @Override
    protected void doPost(ServletRequest req, ServletResponse res) {
        System.out.println("post...");
    }
}

将来页面发送的是GET请求,则会进入到doGet方法中进行执行,如果是POST请求,则进入到doPost方法。这样代码在编写的时候就相对来说更加简单快捷。

类似MyHttpServlet这样的类Servlet中已经为我们提供好了,就是HttpServlet,翻开源码,大家可以搜索service()方法,你会发现HttpServlet做的事更多,不仅可以处理GET和POST还可以处理其他五种请求方式

以下就是源码中的service()方法

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < lastModified) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
            
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);
            
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
            
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }

小结

        通过学习,我们掌握了如何快速创建一个自己的Servlet类

        1、定义Servlet类,并继承HttpServlet

        2、重写HttpServlet中的doPost和doGet方法

        掌握了HttpServlet的原理

        1、根据获取请求方式的不同分别执行不同的doXxx方法

4.7、urlPattern配置

Servlet类编写好后,要想被访问到,就需要配置其访问路径(urlPattern

访问Servlet有两种方式,一种是使用@WebServlet注解,另外一种是配置web.xml配置文件

接下来先说明以下urlPattern配置

1、一个Servlet,可以配置多个urlPattern

@WebServlet(urlPatterns={"/demo1","/demo2"})

2、urlPattern的配置规则

        1)、精确匹配

        2)、目录匹配

        3)、扩展名匹配

        4)、任意匹配

精确匹配

配置路径

@WebServlet("/demo/MyServlet")

访问路径如下

localhost:8080/web-demo/demo/MyServlet
// 其中web-demo为项目名称

目录匹配

配置路径

@WebServlet("/demo/*")

访问路径如下

localhost:8080/web-demo/demo/aaa
localhost:8080/web-demo/demo/bbb
localhost:8080/web-demo/demo/123

// 其中web-demo为项目名称
// demo目录后面输入任何字符均可访问到这个Servlet

扩展名

配置路径

@WebServlet("*.do")

访问路径如下

localhost:8080/web-demo/demo/abc.do
localhost:8080/web-demo/demo/123.do
localhost:8080/web-demo/demo/bbb.do
localhost:8080/web-demo/demo/sd.do

// 其中web-demo为项目名称
// 只要扩展名为 do ,均可访问该Servlet

注意:

        如果路径配置的不是扩展名,那么在路径的前面就必须要加/否则会报错

        如果路径配置的是*.do,那么在*.do的前面不能加/,否则会报错

任意匹配

配置路径

@WebServlet("/")
@WebServlet("/*")

/ 和 /* 的区别
当我们的项目中Servlet配置了 “ / ”,会将tomcat中的DefaultServlet覆盖掉,当其他的urlPattern都匹配不上时会走这个Servlet
当我们的项目中配置了 “ /* ”,意味着匹配任意访问路径

访问路径如下

localhost:8080/web-demo/demo/hello
localhost:8080/web-demo/demo/safagfA
localhost:8080/web-demo/demo/SRGFWEGRB
// 其中web-demo为项目名称

小结

        urlPattern总共有四种配置方式,分别是精确匹配、目录匹配、扩展名匹配、任意匹配

        匹配优先级:精确匹配 > 目录匹配 > 扩展名匹配 > /* > / 无需记,以最终运行结果为准。

4.8、XML配置

前面提到了,要想访问Servlet,就必须配置urlPattern

配置urlPattern有两种方式

        第一种:使用@WebServlet注解,这是Servlet3.0以后支持的

        第二种:xml配置文件配置

其中使用xml配置文件配置的步骤如下:

1、编写Servlet类

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;

public class ServletDemo13 extends MyHttpServlet {

    @Override
    protected void doGet(ServletRequest req, ServletResponse res) {

        System.out.println("demo13 get...");
    }
    @Override
    protected void doPost(ServletRequest req, ServletResponse res) {
    }
}

2、在web.xml中配置该Serlvet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    
    
    <!-- 
        Servlet 全类名
    -->
    <servlet>
        <!-- servlet的名称,名字任意-->
        <servlet-name>demo13</servlet-name>
        <!--servlet的类全名-->
        <servlet-class>com.clear.web.ServletDemo13</servlet-class>
    </servlet>

    <!-- 
        Servlet 访问路径
    -->
    <servlet-mapping>
        <!-- servlet的名称,要和上面的名称一致-->
        <servlet-name>demo13</servlet-name>
        <!-- servlet的访问路径-->
        <url-pattern>/demo13</url-pattern>
    </servlet-mapping>
</web-app>

 这种配置方式和注解比起来,确认麻烦很多,所以建议大家使用注解来开发。但是大家要认识上面这种配置方式,因为并不是所有的项目都是基于注解开发的。       

猜你喜欢

转载自blog.csdn.net/weixin_56058578/article/details/127866158
今日推荐