Servlet (上篇)

哥几个来学 Servlet 啦 ~~

Servlet (上篇)_第1张图片

目录

一、什么是 Servlet

二、第一个 Servlet 程序

1. 创建项目

2. 引入依赖

3. 创建目录

4. 编写代码

5. 打包程序

6. 部署程序

7. 验证程序

三、更方便的部署方式

1. 安装 Smart Tomcat 插件

2. 配置 Smart Tomcat 插件

四、Servlet 的运行原理

五、Servlet 的生命周期


 

一、什么是 Servlet

        Servlet 是一种实现 动态页面 的技术,是一组 Tomcat 提供给程序员的 API,定义了 Java 类 被浏览器访问到(被 Tomcat 识别)的规则,能够帮助程序员简单高效地开发一个 web app

那么问题来了,什么是 动态页面?

Servlet (上篇)_第2张图片

我们先来认识一些什么是 静态页面:

        静态页面 就是内容始终固定的页面即使用户不同/时间不同/输入的参数不同,页面的内容也不会发生变化。(除非网站的开发人员修改源代码,否则页面内容始终不变)。

比如 Tomcat 的主页:

Servlet (上篇)_第3张图片

动态页面:

        动态页面 指的就是 用户不同/时间不同/输入的参数不同,页面的内容发生变化。

比如我们的 CDSN :

Servlet (上篇)_第4张图片

二、第一个 Servlet 程序

1. 创建项目

Servlet (上篇)_第5张图片

注意:这里我们使用的不再是 “intelliJ” ,而是 “Maven” 。

2. 引入依赖

Maven 项目创建完毕后,会自动生成一个 pom.xml 文件。

Servlet (上篇)_第6张图片

我们需要在 pom.xml 中引入 Servlet API 依赖的 jar 包:

① 在中央仓库搜

Maven Repository: Search/Browse/Explore (mvnrepository.com)https://mvnrepository.com/② 然后搜索 "servlet",一般第一个结果就是:

Servlet (上篇)_第7张图片

③ 选择版本,Servlet 的版本要和 Tomcat 匹配,如果我们使用 Tomcat 8.5, 那么就需要使用 Servlet 3.1.0 版本。

Servlet (上篇)_第8张图片

④ 把中央仓库中提供的 xml 复制到项目的 pom.xml 中

Servlet (上篇)_第9张图片

首先要在 这段代码的外围加上 dependencies 标签:

Servlet (上篇)_第10张图片  

然后再将代码复制进去

porn.xml的完整代码是这样的:



    4.0.0

    org.example
    ServletHelloWorld
    1.0-SNAPSHOT

    
        8
        8
        UTF-8
    

    
        
        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        
    

3. 创建目录

当项目创建好了之后,IDEA 会帮我们自动创建出一些目录:

Servlet (上篇)_第11张图片

这些目录中:

  •  src 表示源代码所在的目录
  • main/java 表示源代码的根目录。后续创建.java 文件就放到这个目录中
  • main/resources 表示项目的一些资源文件所在的目录
  • test/java 表示测试代码的根目录

除了这些目录,我们还需要创建一些新的目录/文件

① 创建 webapp 目录 在 main 目录下,和 java 目录并列,创建一个 webapp 目录

② 创建 web.xml 然后在 webapp 目录内部创建一个 WEB-INF 目录,并创建一个 web.xml 文件

Servlet (上篇)_第12张图片

③ 编写 web.xml 

往 web.xml 中拷贝以下代码:




    Archetype Created Web Application

这些代码,我们可以看成是一些约定,可以帮助我们将资源部署到 Tomcat 里~~

        webapp 目录就是未来部署到 Tomcat 中的一个重要目录,我们可以往 webapp 中放一些静态资源,比如 html,css 等。

        在这个目录中还有一个重要的文件 web.xmlTomcat 找到这个文件才能正确处理 webapp 中的动态资源。

4. 编写代码

在 java 目录中创建一个类 HelloServlet让它实现 Servlet 的接口重写 Servlet 的方法

代码如下:

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

@WebServlet("/hello")
public class HelloServlet 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 Servlet");
    }

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

    @Override
    public void destroy() {

    }
}

这个的作用是提供路径 url,待会执行程序时会用到这个 url~~

 千万不要漏了  “ hello ”  前面的 “ / ” !!!!!

这上面的五个方法,我们待会儿再详细讲。

我们目前只在 service() 方法里加了一行代码而已:

5. 打包程序

使用 maven 进行打包,打开 maven 窗口,然后展开 Lifecycle ,双击 package 即可进行打包:

Servlet (上篇)_第13张图片

 如果比较顺利的话,能够看到 SUCCESS 这样的字样:

Servlet (上篇)_第14张图片

        如果代码/配置/环境存在问题,可能会提示 BUILD FAILED,可以根据具体提示的错误信息具体解决。

打包成功后,可以看到在 target 目录下,生成了一个 jar 包:

Servlet (上篇)_第15张图片

这样的 jar 包并不是我们需要的,Tomcat 需要识别的是另外一种 war 包格式。

jar 包和 war 包的区别:

  • jar 包是普通的 java 程序打包的结果,里面会包含一些 .class 文件。

  • war 包是 java web 的程序,里面除了会包含 .class 文件之外,还会包含 HTML、CSS、 JavaScript、图 片、以及其他的 jar 包。打成 war 包格式才能被 Tomcat 识别!!!

另外这个 jar 包的名字太复杂了,我们也希望这个名字能更简单一点。

因此,我们需要:

① 在 pom.xml 中新增一个 packing 标签,表示打包的方式是打一个 war 包:

war

② 在 pom.xml 中再新增一个 build 标签,内置一个 finalName 标签,表示打出的 war 包的名字是 HelloServlet:


    HelloServlet

完整的 pom.xml 如下:



    4.0.0

    org.example
    ServletHelloWorld
    1.0-SNAPSHOT

    
        8
        8
        UTF-8
    

    
        
        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        
    


    war

    
        HelloServlet
    

重新使用 maven 打包,可以看到生成的新的 war 包的结果:

Servlet (上篇)_第16张图片

6. 部署程序

把 war 包拷贝到 Tomcat 的 webapps 目录下:

启动 Tomcat , Tomcat 就会自动把 war 包解压缩:

Servlet (上篇)_第17张图片

7. 验证程序

此时通过浏览器访问 127.0.0.1:8080/HelloServlet/hello

这个路径里的:

“127.0.0.1:8080” 是环回地址

“HelloServlet” 是我们的文件名

Servlet (上篇)_第18张图片

“hello” 则是这里面的url 

就可以看到结果了(结果在 Tomcat 服务器上显示的):

Servlet (上篇)_第19张图片

我们多次点击刷新,那么 Tomcat 服务器就会多次执行 service() 方法里的代码:

三、更方便的部署方式

        手动拷贝 war 包到 Tomcat 的过程比较麻烦,我们还有更方便的办法。此处我们使用 IDEA 中的 Smart Tomcat 插件完成这个工作。

1. 安装 Smart Tomcat 插件

① 菜单 -> 文件 -> Settings

Servlet (上篇)_第20张图片

② 选择 Plugins,选择 Marketplace,搜索 "tomcat",点击 "Install"

Servlet (上篇)_第21张图片

③安装完毕之后,会提示 "重启 IDEA" 

2. 配置 Smart Tomcat 插件

① 点击右上角的 "Edit Configurations"

Servlet (上篇)_第22张图片

② 选择左侧的 "Smart Tomcat"

Servlet (上篇)_第23张图片

③ 在 Name 这一栏填写一个名字(可以随便写)

在 Tomcat Server 这一栏选择 Tomcat 所在的目录,其他的选项不必做出修改。

Servlet (上篇)_第24张图片

其中 Context Path 默认填写的值是项目名称 ,这会影响到后面咱们的访问页面

Servlet (上篇)_第25张图片

④ 点击 OK 之后,右上角变成了

点击绿色的三角号,IDEA 就会自动进行编译、部署、启动 Tomcat 的过程

 此时 Tomcat 日志就会输出在 IDEA 的控制台中,可以看到现在就不再乱码了。

⑤ 访问页面

在浏览器中使用 localhost:8080/HelloServlet/hello 来访问页面:

localhost:8080/HelloServlet/hello 

控制台会执行 service() 方法里的代码:

Servlet (上篇)_第26张图片

四、Servlet 的运行原理

        在 Servlet 的代码中我们并没有写 main 方法,那么对应的 doGet 代码是如何被调用的呢?响应又是如何返回给浏览器的?

Servlet (上篇)_第27张图片

1.当服务器接收到客户端浏览器的请求后,会解析请求的 URL 路径,获取访问的 Servlet 的资源路径。

2.Tomcat 通过 Socket 读取到这个请求(一个字符串),会根据 url 中的 路径 判定这个请求 是 请求的一个静态资源还是动态资源。如果是静态资源,直接找到对应的文件把文件里的内容通过 Socket 返回。如果是动态资源,才会执行到 Servlet 的相关逻辑。

3.Tomcat 会根据 url 中的 Context Path 和 Servlet Path 确定要调用哪个 Servlet 实例的方法

五、Servlet 的生命周期

我们先来回顾一下我们上面代码里的 5 个方法:

方法名称 功能/调用时机
init 初始化方法,在 Servlet 实例化之后被调用一次,只会执行一次
getServletConfig 获取 ServletConfig 对象,也就是 Servlet配置。(了解即可)
service 提供服务的方法,每次服务器被访问时执行,可以执行多次
getServletInfo 获取 ServletInfo 对象,也就是 Servlet的信息。(了解即可)
destory 销毁方法,在 服务器 正常关闭时被调用,只会执行一次

        现在我们分别在 init() 、service() 、destory() 方法里加入 “System.out.println("执行 XXX 方法");”

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

@WebServlet("/hello")
public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("执行 init 方法");
    }

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

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

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

    @Override
    public void destroy() {
        System.out.println("执行 destroy 方法");
    }
}

来观察一下结果

当我们第一次访问 localhost:8080/HelloServlet/hello 的时候,控制台输出结果如下:

Servlet (上篇)_第28张图片

当我们多次访问这个网站时:

 Servlet (上篇)_第29张图片

当我们关闭服务器的时候:

Servlet (上篇)_第30张图片

下面我们来通过上述现象来解析一下 Servlet 的生命周期:

1.被创建:执行 init 方法,只执行一次

Servlet 什么时候被创建?

  • 默认情况下,第一次被访问时,Servlet 被创建
  • 也可以在服务器启动的时候进行创建,不过需要在 web.xml 进行配置(如果我们的 init()方法 要初始化的资源比较多,或者有其他的 Servlet 依赖这个 Servlet 的时候,可以在服务器启动的时候进行创建)

        Servlet 的 init()方法只执行一次,说明 Servlet 在内存中只存在一个对象,因此难免会出现多线程安全问题:比如 抢票 APP ,就涉及到许多的客户端对一个Servlet进行修改操作。

        那么我们应该尽量避免在 Servlet 中创建成员变量,及时创建了成员变量,也不要去修改它。

2.提供服务:执行 service()方法,执行多次

        每次访问 Servlet 时,Service 方法都会被调用一次。

3.被销毁:执行 destroy()方法,只执行一次

        Servlet 被销毁前执行(就像临终遗言)。只有服务器正常关闭,才会执行 destroy()方法。

小结:

        Servlet 是一种实现 动态页面 的技术,是一组 Tomcat 提供给程序员的 API。它的生命周期有 init、service、destroy,就像人的一生:出生、工作、死亡~~

        下一篇我们着重讲解 HttpServlet ~~

Servlet (上篇)_第31张图片

你可能感兴趣的:(网络通信,EE初阶,servlet,前端,tomcat,网络,java-ee)