JavaWEB Servlet

文章目录

1、JavaWEB相关的知识点学习

前端时间和后端之间的信息交互:
   前端确定了访问了文件位置,调用后端的相关执行程序文件

2、对于动态的 Web 应用来讲:一个请求响应中有多少个角色的参与?角色之间是怎么进行通信的呢?

整个 B/S 结构中,什么人参与进去?
1、浏览器的开发者;
2、Web Server 开发团队 Tomcat,Jetty;
3、DB Server MySQL Oracle;
4、Java 程序的开发 Web APP 开发
Web 应用的开发的目录需要遵从一定的规范,在不同的 Web Server 都可以使用
达到通用的实现规范,可以不同的服务器上面使用
Serlet 就是制定的一套规范,可以规范的开发网络应用

3、webapp角色之间遵守什么规范?

HTTP 协议(超文本传输协议)
Browser 和 WebServer 之间存在的协议

Servlet 规范,WebServer 和 Webapp之间存在的协议
Servlet 规范的作用:Web server , Web App之间解耦合,减少依赖程度

JDBC 的规范
Webapp 和 DBServer 之间存在的规范

4、模拟 Servlet 本质

不同的公司,制定了相关行业内部的规则,其他的开发者遵从相关的规则即可;遵循了相关的规则之后,就可以进行互相协同操作;

关于前端访问静态的 html 文件,使用到大服务器的路径就可以
关于前端访问Java 程序,可以通过程序员执行的映射关系,进行程序的访问

5、JavaWeb 只做两件事情

1、编写一个类实现Servlet 接口
2、编写配置文件,编写的类配置到配置文件,在配置文件中指定请求路径和类名之间的关系

注意:

  • 配置文件的文件名字是固定好的,web.properties,配置文件的放的位置都是固定好的,不能乱来
  • 因为项目是需要放在服务器上面运行的,服务器的是其他公式已经写好的东西,所以需要遵从相关的规范,
    不能随便乱来;

6、Servlet 规范中规定了:

合格的 webapp 应该是什么样子的目录结构;
合格的 webapp 拥有什么样子的配置文件
合格的webapp配置文件放在什么地方
合格的webapp的Java程序放在什么地方
这些都是规定好的

Tomcat 服务器需要遵守规范,JavaWEB程序员也是同样需要遵守相关的规范,这样子Tomcat和
webapp 之间才能解耦合;

7、理解Servlet 是一个什么样子的规范?

遵循了Servlet 规范的webapp 可以在不同的额服务器的下面运行
Servlet 规范中包括了什么呢?
1、规定了什么样子的接口
2、规范了一些类
3、规范了web 应用中应该有什么样子的配置文件
4、规范了配置文件的名字
5、规范了配置文件存储的路径
6、规范了webapp 配置文件中的内容…

8、实际操作:开发一个带有 Servlet 的 webapp(重点)

开发步骤(11步):

8.1

  • 1、在webapp 目录下面新建一个目录,起名叫做 crm(crm就是webapp的名字),起名字是根据自己的开发需要设定的

8.2

  • 2、在crm目录下面,新建一个目录:WEB-INF
    这个文件的创建是Servlet 中所规定的,必须是全部大写的才可以

8.3

  • 3、在 WEB-INF 下面新建一个目录叫做 classes 必须是这个名字,Servlet 规范中规定的
    注意:这里存放的是,Java 程序编译之后的class 文件,这李存放的是字节码文件

8.4

  • 4、在WEB-INF 下面创建一个新的目录:lib(不是必须的)
    Java在开发的过程中使用到了第三方的 jar 包,需要使用这个名字,必须使用这个名字

8.5

  • 5、在WEB-INF 新建一个文件叫做:web.xml
    这个文件名字是必须的,文件的名字是必须叫做这个名字的,文件必须放在这里;
    web.xml 是一个配置文件,配置文件中描述了请求路径以及 Servlet 类之间的对照关系
    (这个文件直接从其他的webapp中赋值粘贴即可)
<?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"
  metadata-complete="true">

  <display-name>Tomcat Documentation</display-name>
  <description>
     Tomcat Documentation.
  </description>
</web-app>

8.6

6、编写Java程序,小程序,不能随意开发,必须实现 Servlet 接口

  • Servlet 接口在什么位置?(javaEE 使用的是另外的类库,SE加强版本)

  • Servlet.class 文件

  • Servlet 是JavaEE 中的一员

  • Tomcat 服务器实现了 Servlet 接口,Tomcat 也是需要使用 Servlet 接口的
    所以这个类在 Servlet 下面的文件中是可以找到的;lib 目录下面存在
    Servlet-api.jar 文件

  • 开发的Java源代码可以放置在任何的位置,但是 编译生成的 .class 文件必须放在 classes 文件夹下面

8.7

编写Java程序

8.8

将写好的Java文件编译好形成的 .class 文件放置在:WEB-INF\classes 文件夹下面

8.9

web.xml 文件中编写配置信息,使得 “请求路径” 和 ”Servlet类名“ 关联在一起

注册Servlet 类

<?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"
	metadata-complete="true">

	<servlet>
		<servlet-name>MyServlet</servlet-name>
		<servlet-class>com.luobin.javaweb.HelloServlet</servlet-class>
	</servlet>
  
  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/test</url-pattern>
  </servlet-mapping>

</web-app>

webapp 的文件组成结构

关于目前的 webapp 的文件结构
|-----webapp
	|-----WEB-INF
		|-----classes(存放字节码文件)
		|-----lib(第三方 jar 包)
		|-----web.xml(注册servlet)
	|-----html
	|-----css
	|-----javascript

关于浏览器发送请求到最终的服务器调用Servlet 方法,是一个什么样子的过程?

(下面的实现方法比较的粗糙,有一些细节是没有提到的)
1、用户输入URL在浏览器里面,或者点击超链接
2、Tomcat 服务器收到了请求,截取路径:/crm/test
3、Tomcat服务器在web.xml文件中查找/crm/test 对应的serclet 为:com.luobin.javaweb.HelloServlet
4、Tomcat 服务器通过反射机制,创建com.luobin.javaweb.HelloServlet的对象的service 方法

8.10

启动 tomcat 服务器(mac 使用这个命令可以像 win 在控制台进行输出信息)

catalina.sh run

8.11

在浏览器打开url
http://localhost:8080/crm/test

这个请求路径必须和 web.xml 中的url-pattern 保持一直才可以,否则,运行时可能不成功的;

注意:浏览器上面请求的路径和 web.xml 中的url-pattern 中的唯一区别就是:浏览器上面的请求路径是带着项目名字的;

浏览器上面编写的路径太长的时候,可以使用超链接进行处理;(html 文件只能放置在WEB-INF 目录的外面)

以后不需要编写 main 方法tomcat 在执行的时候,就是相当于 main 方法的功能,javaWeb 程序员,只需要写Servlet 接口的实现类,然后注册到 web.xml即可

8.12关于JavaEE 版本的相关问题

  • JavaEE 当前的最高版本是JavaEE8
  • JavaEE被 Oracle 捐献给了 Apache
  • 以后叫做jakataEE
  • 以后没有JavaEE8 升级之后叫做: jakataEE9

javaEE8 叫做:javax.servlet.Servlet
jakataEE9 叫做:jakata.servlet.Servlet

更改了之后,只能在 Tomcat9 以及以前的版本部署webapp 在之后的版本中是没有办法部署的;

9、向浏览器相应一段 servlet 代码

    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        // 向着控制台记性字符串的打印
        System.out.println("My first servlet , Hello Servlet");

        // 设置相应的文本是普通的文本内容还是 html 等格式的内容
        // 设置这个相应的格式在流的前面进行设置,不要再流的后面设置,因为这样子设置之后,没有修改显示的格式
        // 想要设置就在流的前面设置即可
        response.setContentType("text/html");


        // 如何把一个信息直接输入到浏览器上面?
        // 需要使用ServletResponse 接口: response
        // response表示相应的意思:从服务器向着浏览器发送数据叫做相应

        // 这是一个输出流,负责将字符串输出到浏览器上面
        // 上面的是向着浏览器进行打印,这里的是向着浏览器进行打印
        PrintWriter out = response.getWriter();
        out.println("Hello Servlet ,You are my first Servlet");

        // 向着浏览器相应一段 html 的代码,提供使用
        out.println("<h1>Hello Servlet</h1>");

        // 创建的这个流是不需要刷新的,也是不需要关闭的;Tomcat 是会自动维护的

    }

10、在Servlet 中进行数据库的连接

  • Servlet 是Java程序,所以在servlet 中可以直接编写JDBC进行数据库的连接
  • 在一个 webapp 中,需要将驱动放在 WEB-INF/lib 下面(com.mysql.cj.jdbc.Driver)
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        // 编写 jdbc 代码,进行数据库的连接,记性数据的查询操作
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        // 进行配置文件的获取,获取到进入数据库的权限,进行数据库的操作权限
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        String driver = bundle.getString("driver");
        String url = bundle.getString("url");
        String username = bundle.getString("username");
        String password = bundle.getString("password");

        try {
            // 获取驱动,进行驱动的连接
            Class.forName("com.mysql.jdbc.Driver");

            // 获取连接
            conn = DriverManager.getConnection(url, username, password);

            // 获取预编译的数据库操作对象
            String sql = "select * from dept";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();

            // 处理查询结果集

            while (rs.next()) {
                String dname = rs.getString("dname");
                System.out.println(dname);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

在集成开发环境中(IDEA)开发Servlet 程序

1、先创建一个空的项目,在空的项目下面创建不同的模块进行开发工作的开展
2、新建模块
新建一个普通的JavaSE模块(先不使用JavaEE模块)
3、让Module 变成JavaEE模块

  • 右键项目的名字即可(add Framework Support)
  • (让Module 变成webapp 模块,符合webapp 的规范,或者叫做符合Servlet 规范 Module)
  • 弹出来的窗口中选择 Web Application 选项,选择了这个webapp 的支持之后,IDEA会自动的生成符合Servlet 规范的webapp 文件目录

4、(非必须):根据webApplication 里面的 .jsp 文件删除掉
5、编写servlet(StudentServlet)
6、编写的时候,发现 Servlet 相关jar 包没有导入进去,在这里projects structure 里面进行相关的包的导入即可

11 集成开发环境的文件组织以及注意事项

在这里插入图片描述

注意:

  • 1、lib 文件夹需要放置在WEB-INF 下面,否则类没有加载进去,会产生异常;
  • 2、在html 中设置的超链接需要和 web.xml 里面注册的地址是相同的,否则超链接找不到注册路径无法执行相关的代码,因为根本连类都找不到;
  • 3、当lib 文件夹的位置变了之后,需要重新将 jar 包 add as library这样子才能识别,不然找不到驱动的,也就是找不到 jar 包;

12 Servlet 对象的生命周期

什么时候是被创建出来的,创建了一个还是多个?
Servlet 对象的创建是Tomcat 自动创建的,web 服务器负责创建的;

Servlet 对象是由谁进行维护的呢?
所有的对象的创建到最终的结束,javaweb 开发人员是没有办法进行干预的,Servlet 的对象是由Tomcat 服务器(web 服务器)全权负责的;

Tomcat 服务器通常可以叫做为:web容器(web container)(web server)

12.1 什么是Servlet 生命周期?

生命周期就是对象的刚开始的创建一直到最后的对象的销毁

12.2 Servlet 对象什么时候创建?

在调用的额时候被创建

12.3 Servlet 什么时候被销毁?

12.4 Servlet 对象创建了几个?

调用了几个服务就会创建相关的几个对象

12.5 Servlet 生命周期:表示这一个对象的创建到最终的销毁,整个过程是一个什么样子的;

12.6 我们自己 new 出来的对象受到 web 容器的影响吗?

  • 自己new 出来的Servlet 对象是不受到web 容器管理的;

  • web 容器创建出来的Servlet 对象,使得Servlet 对象都会放置在一个集合当中:HashMap,只有放在 HashMap,只有放在 HashMap 容器里面的对象才会被Tomcat 服务器进行管理,自己创建出来的对象是不会放进去的,所以就不会被管理;

  • web 容器底层是应该具有一个 HashMap 这样子的集合,用来存储Servlet 对象以及请求路径之间的关系;

12.7 服务器在启动的时候,Servlet 对象有没有被创建出来?(默认情况下面)

经过了实验,在服务器启动了之后,Servlet 对象开始并没有被创建出来,当在访问其注册的地址的时候,对象会被创建出来;
在请求的时候,才会被创建出来是比较合理的,在用户发请求之前是先不会被创建出来的,只有在用户请求了之后,才会被创建出来,对于资源的节约是有一定的帮助作用的;

为什么在调用的时候,访问的时候,才创建相关的对象呢?
因为提前创建好的对象没有什么用户,不用的话,反而一直在占用内存空间,造成了空间的浪费;

想让Servlet 对象在服务器启动的时候就把对象创建出来的办法有:

    <servlet>
        <servlet-name>aservlet</servlet-name>
        <servlet-class> com.luobin.servlet.AServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>aservlet</servlet-name>
        <url-pattern>/a</url-pattern>

    </servlet-mapping>

添加了 标签在后面加上整数,整数的数字越小,其优先级别是越高的;
这个整数是不能使用负数的;

通过上面的小实验得到的结论:
1、用户在第一次请求的时候,对象被创建,也就是被实例化了
2、Aservlet 对象被创建出来之后,Tomcat 先调用了 init 方法(因为先创建出来的对象,所以在后面才可以进行 init 方法的调用)
3、服务器启动了之后,在网页进行刷新的时候,会一直调用 service 方法,init 以及构造方法都只是会执行一次,初始化的时候执行一次;
(Servlet 是一种假单例模式)
init 无参数构造方法,只是会在第一次用户发送请求的时候执行;

只要用户发送请求,service 方法必定会被执行的;请求 100 此 会被调用100 次;

4、Servlet 方法的 destroy 方法知识会被 Tomcat 服务器调用一次
destrory 在服务器被关闭的时候被调用的;服务器在进行对象的销毁之前,会调用 destroy 方法;

调用 destroy 方法的时候,对象销毁了还是没有销毁?
没有被销毁的,在销毁之前就会调用这个方法;destroy 是一个实例方法,实例方法被调用了,说明实例是存在的,也就是对象是存在的;

13、创建一个服务的相关代码 AServlet

package com.luobin.servlet;

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

/**
 * @author Doraemon
 * @version 1.0
 * @date 2021/11/10 2:36 下午
 */

    // 在创建对象的时候 Tomcat 会自动的进行对象的创建,只会创建出来一个对象,但是不是一个真的单例,是一个假的单例
    // 是多线程共享的一个对象
    // 真的单例模式是构造参数私有化的,这个显然不是的
public class AServlet implements Servlet {
    // 无参数构造函数


    public AServlet() {
        System.out.println("AServlet 无参数构造方法执行了!");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("AServlet's init method execute");
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("AServlet's service method execute");
    }


    /**
     *  只是会执行一次
     *  Tomcat 服务器在销毁对象之前进行这个方法的执行
     *  在这个方法中可以编写在销毁前面的准备
     *  比如说在AServlet 对象中开启了一些资源,这些资源是流,可能是数据库连接,关闭服务器的时候,需要关闭相关的流,这些关闭的代码可以书写在这个地方
     */
    @Override
    public void destroy() {
        System.out.println("AServlet's destroy method execute");
    }

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

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

13.1、Servlet 对象的生命周期可以类比于人的生命:

  • Servlet 构造方法的执行,相当于人出生了
  • Servlet init 方法的执行,标志着拟正在接受教育,被初始化
  • Servlet service() 方法的执行,表示你已经开始工作了,为人类开始提供服务
  • Servlet destroy() 方法的执行表示,在生命的最后的所得事情

13.2、关于servlet 类中方法的调用次数?

  • 构造方法只会执行一次
  • init 方法执行一次
  • destroy 只会执行一次
  • service 用户发送一次请求执行一次,发送多次请求,执行多次的方法

当创建了一个有参数的构造方法之后,这个时候没有创建无参数的构造方法的话是出现一系列的问题的;
此时会报 500 错误,在http 协议中这是一个服务器端的错误,所以在具体的开发过程中,是不建议自己来定义构造方法的,因为定义不好的时候,一不小心会导致无法实例化Servlet 对象的;

13.3、思考:init 构造方法几乎可以在同一时间同时执行,但是为什么需要写两个方法呢?合并到一起不行吗?

因为单独写了一个 init 方法之后,此时的init 方法中可以书写一些报错的信息,方便控制程序的执行;

在实际的开发中不建议写构造方法,因为有可能写一个有参数的构造方法,会导致一些莫名其妙的错误,此时的 init 方法的作用就体现出来了

13.4、init service destroy 方法中使用最多的是什么方法?

使用最多的是service 方法,
init 只是会执行一次;(初始化线程池等)
dextroy 使用的也是比较少的;

14、适配器的相关介绍

问题:早编写Servlet 类直接实现 Servlet 接口存在问题:
我们只是需要一个service 方法,但是直接世界 Servlet 类会产生很多没有什么用处的代码,或者使用的次数比较少的代码,代码比较丑陋,这个时候可以使用适配器设计模式;

适配器设计模式:手机不能直接插到220 V的电源上面,充电器头通过了适配,可以进行充电的操作;

在程序中写一个 GenericServlet 类

这是一个抽象类,什么方法使用的频繁,将其写为抽象方法,让其子类,即Servlet 类进行抽象方法的实现,可以使得代码的书写变得简洁些;

这样子就会达到了适配器的效果,使得代码的数量得到一定的减少,维护起来更加的方便

14.1、GenericServlet 类的改造,可以更加的方便子类程序的编写

思考:

  • 提供了GenericServlet 之后, init 还是会执行吗?
    肯定会执行的,子类没有,默认执行父类的 init 方法;
  • init 方法是谁调用的呢?
    Tomcat 服务器会进行调用
  • init 方法中的 ServletConfig 对象谁创建的,谁传过来的?
    Tomcat 服务器创建的,然后传递了进去
    Tomcat 服务器先创建了Servlet 对象建立,然后进行传递进去;

14.2、模拟Tomcat 服务器里面执行的代码

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值