菜鸟学JavaWeb之——入门、Tomcat安装,部署,创建Web项目、Servlet执行原理,生命周期

引入

相关概念

  • 软件架构

    • C/S:客户端 / 服务器端
    • B/S:浏览器 / 服务器端

    所谓CS是指 Client—Server(CS架构:客户端和服务器要分离,分别要开发出来客户端和服务器)

    ​ 优势:传输的数据是可以自定义的、传输的通道时加密的、对于数据具有更好的安全性

    ​ 缺点:开发成本大、使用成本大(必须要下载客户端装上才能用)

    Java不适合做CS架构,做出来的用户界面奇丑无比

    所谓的BS是指 Browser—Server

    ​ 特点:传输使用协议一般是HTTP协议(超文本传输协议),而HTTP承载层使用TCP协议,而对于开发人员,要做的事情就是去实现一个前端的界面,让浏览器可以解析出来这个界面就可以了,传输的数据不是那么的安全,传输数据的格式是既定的。

    ​ 优点:开发成本低,特别低、使用成本低,也特别低。

  • 资源分类

    • 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析。

      如:HTML、CSS、JavaScript

    • 动态资源:每个用户 访问相同资源后,得到的结果可能不一样,称为动态资源。动态资源被访问后,需要先转换为静态资源,在返回给浏览器。

      如:servlet、jsp、php、asp

  • 网络通信三要素

    • IP:电子设备(计算机)在网络中的唯一标识

    • 端口:应用程序在计算机中的唯一标识。0~65535

    • 传输协议:规定了数据传输的规则(就比如浏览器和客户端交流需要用什么语言,英语?汉语?)

      TCP协议:安全,三次握手,速度慢

      UDP协议:不安全,速度快

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ttvMma8I-1586143993118)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405164541347.png)]

一、Web服务器软件

引入

服务器:安装了服务器软件的计算机

服务器软件:接受用户的请求,处理请求,做出响应

Web服务器软件(也称:Web容器):接受用户的请求,处理请求,做出响应

  • 在Web服务器软件中,可以部署Web项目,让用户通过浏览器访问这个项目

常见的Java相关的网络容器

  • webLogic(Oracle公司)、webSphere(IBM公司)、JBOSS(JBOSS公司):支持所有的JavaEE规范,收费
  • Tomcat:Apache基金组织,中小型JavaEE服务器,仅支持少量的JavaEE规范(如:Servlet、JSP)

1. Tomcat

Tomcat:Web容器

1.1 下载、安装、启动、配置、部署

官网:https://tomcat.apache.org/download-80.cgi

根据需求,下载zip压缩包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qQo1uzNt-1586143993120)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405170738306.png)]

下载成功后解压文件夹即安装成功!

目录结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QdL8rSDH-1586143993125)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405171425091.png)]
启动

  • bin/startup.bat:运行即可
  • 访问:浏览器输入:http://localhost:8080
  • 可能遇到的问题
    • 黑框一闪而过(JAVA_HOME没有配置)

正确配置方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jw9wxsXy-1586143993127)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405172212977.png)]

startup.bat是批处理文件,里面写的就是dos命令。

catalina.bat中有一条dos命令,使用环境变量的JAVA_HOME,找到JDK,然后才能运行Tomcat。Tomcat是纯Java编写的,他的启动依赖于电脑上安装的JDK

**修改端口号(默认是8080):**在conf/server.xml中修改

部署:

  • 直接将项目放在webapps目录下即可。

    ​ 或者:将项目打包成war包,再将war包放在webapps目录下。(war包会自动解压缩)

2. 将Tomcat集成到IDEA中,并且创建JavaEE的项目,部署项目

2.1 手动集成Tomcat

Run—>Edit Configurations

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFLzHADU-1586143993127)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405175600327.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gxGsRE7p-1586143993129)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405175737404.png)]

接下来点击apply就成功了

2.2 创建Web项目

一般Tomcat的启动都伴随这Web项目的启动。所以接下来创建Web项目(创建web项目时其实就会自动集成好了Tomcat)

File—>New—>Project

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o8LOTqj0-1586143993129)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405175237969.png)]

部署:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VL5Z6BoL-1586143993130)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405184118817.png)]虚拟路径指项目的访问路径

热部署:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JSq0tCTT-1586143993130)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405180842783.png)]

二、Servlet

概念:server applet:运行在服务器端的小程序

  • Servlet就是一个接口,这个接口定义了Java类被浏览器访问到(Tomcat识别)的规则

将来自定义一个类,实现Servlet接口,覆写方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vzca7jWL-1586143993130)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405182857343.png)]

配置Servlet

写一个Servlet就要配置一个Servlet

web.xml是Tomcat找到其他类的指路标,然后用类加载反射机制加载这些类,所以要在web-app里写好路标(xml其实就是用来写后台的配置文件用的)

<?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-name>demo1</servlet-name>
        <servlet-class>com.home.java.service.ServletDemo1</servlet-class>  
    </servlet>
    
    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1.do</url-pattern>
    </servlet-mapping>

</web-app>

1. Tomcat执行Servlet的执行原理:

  • 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
  • 查找web.xml文件,看是否有对应的标签体内容
  • 如果有,则在找到对应的全类名
  • Tomcat会将字节码文件加载今内存,并创建其对象
  • 调用其方法

如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qxd7aX8P-1586143993131)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200405190701042.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-10alyhiP-1586143993131)(C:\Users\张澳琪\AppData\Roaming\Typora\typora-user-images\image-20200406112950261.png)]

2. Servlet的生命周期

  • init():初始化方法,在Servlet被创建时执行。且只会执行一次
  • service():提供服务方法,每一次Servlet被访问时,执行。执行多次
  • destroy():销毁方法,在服务器正常关闭时,才会执行。执行一次
package com.home.java.service;
/**
 * @author ZAQ
 * @create 2020-04-05 18:49
 */
public class ServletDemo1 implements Servlet {
    
    

    public ServletDemo1() {
    
    
        System.out.println("我是构造方法");
    }

    @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() {
    
    

    }
}

Servlet什么时候被创建?

  • 默认情况下,第一次被访问时,Servlet被创建

  • 但是也可以配置执行Servlet的创建时机

    在标签下配置

    • 设置第一次被访问时创建

      <load-on-startup>的值为负数

    • 设置在服务器启动时创建

      <load-on-startup>的值为0或正整数

执行顺序:先执行ServletDemo1()方法创建对象(构造器),然后执行init()方法,然后是Service()方法

Servlet的init方法只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的

  • 多个用户同时访问时,可能存在线程安全问题
  • 解决:尽量不要在servlet中定义成员变量。即使定义了成员变量,也不要修改其值

destroy()方法在Servlet被销毁之前执行,一般用于释放资源(init()用于加载资源)

3. Servlet注解配置

由于每个Servlet都要在xml文件中配置,过于麻烦,所以引入注解配置,方便快捷

注解配置:只需要在类上面写@WebServlet("/demo1.do")即可

路径定义规则:

  • /xxx
  • *.do(注意没有 / )

Tomcat真正访问的是“Tomcat部署的web项目”,“Tomcat部署的web项目”对应着“工作空间项目”的web目录下的所有资源。

WEB-INF目录下的资源不能被浏览器直接访问。

4. Servlet的体系结构

Servlet—接口

  • GenericServlet—抽象类(实现了Servlet接口)
    • HttpServlet—抽象类(继承GenericServlet)

GenericServlet:将Servlet接口中的其他的方法做了默认空实现,只将service()方法作为抽象

HttpServlet:对Http协议的一种封装,简化操作

  • 定义类继承HttpServlet
  • 覆写doGet/doPost方法

前端通过form表单发送数据到Servlet中,我们可以通过Servlet中的service()里的一些操作获取这些数据。所以service()里的第一件事就是获取数据,但是在获取数据之前要判断form表单的请求方式。这个过程是繁琐的,并且是每个Servlet都要完成的操作,所以Sun公司提供了一个HttpServlet类,他帮助我们完成了这些操作,以后我们不再需要写判断请求方式的过程,只需要重写doGet()、doPost()方法即可。

HttpServlet源码:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        String method = req.getMethod();//获取请求方式
        long lastModified;
    	//判断是那种请求方式,如果是GET就...如果是Post就...
        if (method.equals("GET")) {
    
    
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
    
    
                this.doGet(req, resp);
            } else {
    
    
                long ifModifiedSince;
                try {
    
    
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
    
    
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
    
    
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);//如果是GET请求,则调用doGet
                } 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);//如果是Post请求,则调用doPost
        } 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);
        }

    }

内容持续更新中…

Guess you like

Origin blog.csdn.net/ysf15609260848/article/details/105340751