都2024年了,Servlet还有必要学习吗?一文带你快速了解Servlet_servlet用得多吗(1)

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取


请把这个依赖的范围设置为 provided ,即只在编译和测试的过程中有效,最后生成的 war 包中不会加入这个依赖 jar 包,因为 TomCat 文件中本身就带有这个 jar 包,如果不使用这个范围,则会出现冲突。添加依赖范围时只需要在依赖坐标下面添加 `<scope>` 标签。


**第二步**:


定义一个类,用来实现 Servlet 接口,并重写接口中的所有方法。



public class ServletDemo implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {

}

@Override
public ServletConfig getServletConfig() {
    return null;
}

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    System.out.println("Hello");
}

@Override
public String getServletInfo() {
    return null;
}

@Override
public void destroy() {

}

}


**第三步**:


通过 `@WebServlet` 注解,配置其访问路径,如图:


![](https://img-blog.csdnimg.cn/img_convert/ecc2df073d7f87a2d02a53792f4dfef2.png)


**第四步**:


启动 TomCat ,在浏览器中访问该 Servlet,


![image-20230204111801726](https://img-blog.csdnimg.cn/img_convert/d7a1814c0ad17f4505e2d448185888d9.png)


此时,浏览器页面展示 Hello World!因为我们项目中有一个默认的 html 文件,文件中内容被展示到浏览器。此时往浏览器的 url 路径中添加刚才使用 Java 注解配置的访问路径,idea 控制台就会打印刚才在 servlet() 方法中定义的输出内容。


我们并没有实例化这个 Servlet 类的对象,那么为什么 servlet() 方法被成功执行了呢?学习完后面的内容以后这个问题就不难理解了。


## 4. 执行流程


要想知道我们并没有手动创建 ServletDemo 这个类的实例化对象,为什么它的方法 servlet() 被成功执行这个问题,我们就要了解其执行流程。


![image-20230204151930520](https://img-blog.csdnimg.cn/img_convert/b0fd8c4e9f7cb955a09b71423d0bd239.png)


在上面的例子中,我们已经写好一个 Servlet 的项目,并且将其部署到了 Web 服务器 TomCat 中,此时我们可以根据对应的 url 在浏览器中访问该服务器资源。


浏览器发出 `http://localhost:8080/servlet-project/demo`请求,这个请求大致分为3部分,分别是:


* 根据`http://localhost:8080`找到要访问的 Tomcat 服务器
* 根据`servlet-project`找到部署在 TomCat 服务器中的 Web 项目
* 根据`demo`找到访问的项目中的具体 Servlet,因为我们已经通过注解给 Servlet 配置了具体的访问路径


此时 Web 服务器软件 TomCat 将会创建一个 ServletDemo 的对象,这个对象称为 Servlet 对象,并且该对象的 service() 方法也会被服务器自动调用。


当 service() 方法被调用执行后就会向客户端浏览器发送响应数据。上面的例子中我们没有向浏览器发送具体的数据,要想实现这个功能,我们就要继续学习 ServletRequest 类和 ServletResponse 类。


其中 ServletRequest 中封装了请求数据,而 ServletResponse 中则是封装的响应数据,通过这两个类的对象就可以实现前后端的数据交互了。


## 5. 生命周期


在 Servlet 执行流程中,我们说到,Servlet 对象是由 Web 服务器创建的,那么具体创建时机是什么时候呢?要想了解这个问题,就要学习 Servlet 的生命周期。


对象的生命周期是指一个对象从创建到销毁经历的整个过程。Servlet 运行在 Servlet 容器(Web 服务器)中,其生命周期由容器来管理,大致分为四个阶段:


1. 加载和实例化
2. 初始化
3. 请求处理
4. 服务终止


**加载和实例化**:默认情况下,当 Servlet 第一次被访问时,由容器创建 Servlet 对象,有时创建 Servlet 是比较耗时的,那么第一次访问就比较耗费时间,用户体验比较差。Servlet 提供了解决这个问题的方法,通过具体的配置可以实现在服务器启动的时间来创建 Servlet 对象,提高了访问速度。


只需要使用下面这个简单的配置:



@Webservlet(urlPatterns = “/demo”,loadOnStartup=1)


其中 loadOnStartup 参数如果是负整数,则 Servlet 对象在第一次访问时创建,如果参数的值为 0 或者正整数的话,则会在服务器启动时创建,并且数字越小优先级越高。


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


**请求处理**:每次请求 Servlet 时,Servlet 容器都会调用 Servlet 的 service() 方法来对请求进行处理,该方法会被多次调用。


**服务终止**:当需要释放内存或者是容器关闭时,容器都会调用 Servlet 的 destroy() 方法完成资源的释放,在 destroy() 方法调用之后,容器会释放实例化对象,随后被 Java 垃圾回收机制处理,该方法只会被调用一次。注意,此时的服务器关闭指的是正常关闭非强制关闭。


## 6. 方法初识


Servlet 是一个接口,其中一共有 5 个方法,当我们的类实现了这个接口以后,必须将这 5 个方法全部实现。这 5 个方法分别是:


* 初始化方法:void init()
* 提供服务方法:void service()
* 销毁方法:void destroy()
* 获取Servlet信息方法:String getServletInfo()
* 获取ServletConfig对象方法:servletConfig getServletConfig()


其中,前三个方法我们在之前的生命周期中已经接触过了,在 Servlet 被创建时,会执行 init() 方法进行初始化操作,此方法只会执行一次,每次 Servlet 被访问时都会执行 service() 方法,而 Servlet 被销毁时,则会执行 destroy() 方法,释放对象。


我们看到在进行初始化操作时,会往 init() 方法中传入 ServletConfig 类对象,如下:



@Override
public void init(ServletConfig servletConfig) throws ServletException {
//…
}


所以在 getServletConfig() 方法中,我们只需要将容器创建的 ServletConfig 对象返回即可,而在 getServletInfo() 方法中先返回一个空字符串处理,如下:



private ServletConfig servletConfig;

public void init(ServletConfig config) throws ServletException {
this.servletConfig = config;
System.out.println(“init…”);
}
public ServletConfig getServletConfig() {
return servletConfig;
}

public String getServletInfo() {
return “”;
}


其中最常用的是前面三个方法,这里我们都是只做了解,后面等对整个 Servlet 体系有了认知以后,再深入学习。



> 
> 小tips:这也是我们学习编程一个很重要的方法论,先广度后深度,前期不用深入的了解其底层的含义,否则容易导致我们钻牛角尖,得不偿失。
> 
> 
> 


## 7. 体系结构


在我们编写的实现 Servlet 接口的类中,我们更加关注的是 service() 方法,有没有一种方式让我们创建 Servlet 更加简便高效呢?学习完 Servlet 的体系结构之后,这个问题就变得简单了。


我们开发 B / S 架构的 Web 项目时,其实都要对 HTTP 协议进行封装,所以我们自定义的 Servlet 要继承 HttpServlet ,Servlet 的体系结构如下:


![image-20230204172421386](https://img-blog.csdnimg.cn/img_convert/c6898fa161a908a3944f2ba618c2925a.png)


我们想要实现的是,在客户端发送 GET 请求给 Servlet 后,执行一种逻辑,当客户端发送 POST 请求给 Servlet 后执行另外一种逻辑…


在 HttpServlet 类中就实现了这样的功能,HttpServlet 类会判断页面发送的请求方式,根据不同的请求方式定义了不同的执行方法,例如 doGet,doPOST 等,


例如下面是部分HttpServlet类的源码:



protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
    long lastModified;
    if (method.equals("GET")) {
        lastModified = this.getLastModified(req);
        if (lastModified == -1L) {
            this.doGet(req, resp);
        } else {
            long ifModifiedSince = req.getDateHeader("If-Modified-Since");
            if (ifModifiedSince < lastModified) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
    } else if (method.equals("HEAD")) {
        lastModified = this.getLastModified(req);
        this.maybeSetLastModified(resp, lastModified);
        this.doHead(req, resp);
    } else if (method.equals("POST")) {
        this.doPost(req, resp);
    } else if (method.equals("PUT")) {
        this.doPut(req, resp);
    } else if (method.equals("DELETE")) {
        this.doDelete(req, resp);
    } else if (method.equals("OPTIONS")) {
        this.doOptions(req, resp);
    } else if (method.equals("TRACE")) {
        this.doTrace(req, resp);
    } else {
        String errMsg = lStrings.getString("http.method\_not\_implemented");
        Object[] errArgs = new Object[]{method};
        errMsg = MessageFormat.format(errMsg, errArgs);
        resp.sendError(501, errMsg);
    }

}

我们自己定义的实现类只需要继承自 HttpServlet 类,并且重写 HttpServlet 类中的 doGet 这样的方法,以此来实现不同的处理逻辑。例如:



@WebServlet(“/demo”)
public class ServletDemo 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…”);
}
}


## 8. urlPattern 配置


Servlet 编写好以后,要想被浏览器访问,就需要配置其访问路径,例如前面案例中我们就通过 Java 注解的方式,给 Servlet 配置了访问路径,如图:


![image-20230204175956128](https://img-blog.csdnimg.cn/img_convert/29b85020f68ad8d60cf4a9c7509bf1c4.png)


一个 Servlet 可以配置多个访问路径,urlPattern 的配置有以下几个规则:


* 精确匹配
* 目录匹配
* 扩展名匹配
* 任意匹配


**精确匹配**:


当我们配置如下的访问路径:



@WebServlet(“/user/demo”)


此时我们在浏览器中访问时的 url 为:


![image-20230204181440797](https://img-blog.csdnimg.cn/img_convert/16ec12cd8df6b4310f4d02abab9a075f.png)


**目录匹配**:


当我们配置如下的访问路径:



@WebServlet(“/user/*”)


此时我们在浏览器中的访问 url 为:



![img](https://img-blog.csdnimg.cn/img_convert/18f3b7d3e526f5ca0e32eaf746c8340d.png)
![img](https://img-blog.csdnimg.cn/img_convert/f0188b5175c725086bd28fab8bb97c61.png)
![img](https://img-blog.csdnimg.cn/img_convert/cb17c3ffef463b5c90bd924e58f82af5.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

的访问 url 为:



[外链图片转存中...(img-xdjToPBI-1715835594401)]
[外链图片转存中...(img-DsQM4v3v-1715835594401)]
[外链图片转存中...(img-FPcO4LWf-1715835594402)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值