Web核心-Http-Tomcat-Servlet学习记录

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

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

JavaWeb 技术栈

  • B/S 架构:Browser/Server,浏览器/服务器 架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可

    好处:易于维护升级:服务器端升级后,客户端无需任何部署就可以使用到新的版本

  • 静态资源:HTML、CSS、JavaScript、图片等。负责页面展现

  • 动态资源:Servlet、JSP 等。负责逻辑处理

  • 数据库:负责存储数据

  • HTTP协议:定义通信规则

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

HTTP

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

HTTP 协议特点

  • 基于TCP协议:面向连接,安全
  • 基于请求-响应模型的:一次请求对应一次响应
  • HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
    • 缺点:多次请求间不能共享数据。Java中使用会话技术(Cookie、Session)来解决这个问题
    • 优点:速度快

HTTP-请求数据格式

请求数据分为3部分

  1. 请求行:请求数据的第一行。其中GET表示请求方式,/表示请求资源路径,HTTP/1.1表示协议版本
  2. 请求头:第二行开始,格式为key:value形式。
  3. 请求体: POST请求的最后一部分,存放请求参数

GET / HTTP/1.1

Host: www.itcast.cn

Connection: keep-alive

User-Agent: Mozilla/5.0 Chrome/91.0.4472.106

POST / HTTP/1.1

Host: www.itcast.cn

Connection: keep-alive

Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 Chrome/91.0.4472.106

username=superbaby&password=123456

GET请求和 POST请求区别

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

    POST请求请求参数在请求体中

  • GET请求请求参数大小有限制,

    POST没有

常见的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等。

HTTP-响应数据格式

响应数据分为3部分

  • 响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述
  • 响应头:第二行开始,格式为key:value形式
  • 响应体: 最后一部分。存放响应数据

HTTP/1.1 200 OK

Server: Tengine

Content-Type: text/html

Transfer-Encoding: chunked…

<html>

<head>

​ <title></title>

</head>

<body></body>

</html>

常见的HTTP 响应头

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

Web服务器 - Tomcat

Web服务器

Web服务器是一个应用程序(软件),对 HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是“提供网上信息浏览服务” 。

Tomcat

简介

  • 概念: Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/ISP少量JavaEE规范。
  • JavaEE: Java Enterprise Edition,Java企业版。指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、Java lDL、JTS、JTA、JavaMail、JAF
  • Tomcat 也被称为 Web容器、Servlet容器。Servlet 需要依赖于 Tomcat才能运行
  • 官网:https://tomcat.apache.org/

基本使用:安装、卸载、启动、关闭、配置、部署项目

  • 下载:官网下载

  • 安装:绿色版,直接解压即可

  • 卸载:直接删除目录即可

  • 启动:双击:bin\startup.bat

    • Tomcat输出日志的编码为UTF-8,而Windows控制台为GBK,一般会出现乱码。

      修改conf/ logging.properties

      java.util.logging.ConsoleHandler.encoding = GBK
      
  • 关闭:

    1. 直接×掉运行窗口:强制关闭
    2. bin\shutdown.bat:正常关闭
    3. Ctrl+C:正常关闭
  • 配置:

    修改启动端口号:conf/server.xml

        <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    注:HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号

  • Tomcat 部署项目:

    将项目放置到 webapps 目录下, 即部署完成

    一般 JavaWeb项目会被打成war包,然后将 war包放到 webapps目录下,Tomcat会自动解压缩 war文件

IDEA中创建Maven Web项目

Web项目结构

Maven Web项目结构:开发中的项目 :

在这里插入图片描述

部署的JavaWeb项目结构:开发完成,可以部署的项目 :

  • 编译后的Java字节码文件和resources的资源文件,放到WEB-INF下的classes目录下
  • pom.xml中依赖坐标对应的jar包,放入WEB-INF下的lib目录下
使用骨架创建

骨架:项目模板

创建一个新项目或模块,再点击Maven Archetype,在Archetype中选择。

org.apache.maven.archetypes:maven-archetype-webapp

点击Create创建完成。

可以发现,在main下没有Java目录,右键main,New,Directory,直接选择Java就行。

不适用骨架创建

创建一个新项目或模块:File->New -> Module…或者Project…

我这里创建一个模块,选择New Module,Build System选择Maven。

点击Create创建完成。

再pom.xml中编写打包方式:

    <packaging>war</packaging>

然后要创建webapp目录,可以手动创建,也可以自动创建。

自动创建:打开Project Structure,选择Facets,右键Web,点击Add,选择Web,选择刚刚创建的项目。

修改Deployment Descriptors中的路径。

修改Web Resource Directories中的路径。

点击Apply,再点击OK即可。

IDEA中使用Tomcat

在IDEA中集成使用Tomcat有两种方式,分别是集成本地TomcatTomcat Maven插件

集成本地Tomcat

点击Edit Congfigurations…,再点击+号,选择Tomcat Server、Local。

点击Application server后的configure…,选择Tomcat Home的路径。点击OK。

接下来是部署,切换到Deployment。点击Deploy at the server startup下的+号,再点击Artifact…,选择tomcat-deom:war 即可。

最后点击apply,再点击OK就完成了。

Tomcat Maven插件

在pom.xml中添加Tomcat插件,可以使用快捷键alt+(fn)+ins(ert)

  <build>
    <finalName>tomcat-deom</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
      </plugin>
    </plugins>
  </build>

在项目中,右键->Run Maven -> tomcat7:run运行

Maven Tomcat插件目前只有Tomcat7版本,没有更高的版本可以使用

使用Maven Tomcat插件,要想修改Tomcat的端口和访问路径,可以直接修改pom.xml

  <build>
    <finalName>tomcat-deom</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>8000</port><!--访问端口号 -->
          <!--项目访问路径-->
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>

Servlet

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

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

快速入门

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

    	...
    
      <dependencies>
    
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.1</version>
            <!--
          provided指的是在编译和测试过程中有效,最后生成的war包时不会加入
           因为Tomcat的lib目录中已经有servlet-api这个jar包,如果在生成war包的时候生效就会和Tomcat中的jar包冲突,导致报错
        -->
          <scope>provided</scope>
        </dependency>
    
      </dependencies>
    
      <build>
        <finalName>web-demo</finalName>
        <plugins>
          <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
          </plugin>
        </plugins>
      </build>
    
    </project>
    
    
  2. 创建:定义一个类,实现Servlet接口,并重写接口中的所有方法,并在service方法中输出一句话

    public class ServletDemo1 implements Servlet {
          
          
        public void init(ServletConfig servletConfig) throws ServletException {
          
          
    
        }
    
        public ServletConfig getServletConfig() {
          
          
            return null;
        }
    
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
          
          
            System.out.println("Servlet:Hello World!");
        }
    
        public String getServletInfo() {
          
          
            return null;
        }
    
        public void destroy() {
          
          
    
        }
    }
    
  3. 配置:在类上使用@WebServlet注解,配置该Servlet的访问路径

    @WebServlet("/demo1")
    public class ServletDemo1 implements Servlet {
          
          
        public void init(ServletConfig servletConfig) throws ServletException {
          
          
    
        }
    
        ...
    }
    
    
  4. 访问:启动Tomcat,浏览器输入URL访问该Servlet

Servlet执行流程

  • 浏览器发出http://localhost:8080/web-demo/demo1请求,从请求中可以解析出三部分内容,分别是localhost:8080web-demodemo1
    • 根据localhost:8080可以找到要访问的Tomcat Web服务器
    • 根据web-demo可以找到部署在Tomcat服务器上的web-demo项目
    • 根据demo1可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配
  • 找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象然后调用对象中的service方法
    • service方法中有ServletRequest和ServletResponse两个参数,ServletRequest封装的是请求数据,ServletResponse封装的是响应数据

Servlet生命周期

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

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

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

    默认情况,Servlet会在第一次访问被容器创建。

    也可以在服务器启动的时候来创建Servlet:

    /*
    loadOnstartup的取值有两类情况
    	(1)负整数:第一次访问时创建Servlet对象
    	(2)0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高
    */
    @WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
    
  2. 初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次

  3. 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理

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

可以在Terminal命令行中,使用mvn tomcat7:run启动,然后再使用ctrl+c关闭tomcat

package com.xlr.web;

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

@WebServlet(urlPatterns = "/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {
    
    

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

    public ServletConfig getServletConfig() {
    
    
        return null;
    }

    /**
     * 提供服务
     * 1.调用时机:每一次Servlet被访问时,调用
     * 2.调用次数: 多次
     */
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    
    
        System.out.println("Servlet:Hello World!");
    }

    public String getServletInfo() {
    
    
        return null;
    }

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

Servlet方法

  • 初始化方法,在Servlet被创建时执行,只执行一次
void init(ServletConfig servletConfig)
  • 提供服务方法, 每次Servlet被访问,都会调用该方法
void service(ServletRequest servletRequest, ServletResponse servletResponse)
  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
void destroy() 

剩下的两个方法是:

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

Servlet体系结构

图片描述

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

@WebServlet("/demo4")
public class ServletDemo4 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方法被执行了

  • 要想发送一个POST请求,需要编写一个form表单来发送请求,在webapp下创建一个a.html页面,内容如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <form action="/web-demo/demo4" method="post">
      <input name="username"><input type="submit">
    </form>
    
    </body>
    </html>
    

    启动测试,即可看到doPost方法被执行了。

前端发送GET和POST请求的时候,参数的位置不一致,GET请求参数在请求行中,POST请求参数在请求体中。为了能处理不同的请求方式,我们得在service方法中进行判断,然后写不同的业务处理。

@WebServlet(urlPatterns = "/demo5",loadOnStartup = 1)
public class ServletDemo5 implements Servlet {
    
    

    public void init(ServletConfig servletConfig) throws ServletException {
    
    
        System.out.println("init...");
    }

    public ServletConfig getServletConfig() {
    
    
        return null;
    }

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    
    
        //获取请求方式,根据不同的请求方式进行不同的业务处理
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        //1. 获取请求方式
        String method = request.getMethod();

        //2. 判断
        if ("GET".equals(method)) {
    
    
            // get方式处理逻辑
        } else if ("POST".equals(method)) {
    
    
            // get方式处理逻辑
        }

    }

    public String getServletInfo() {
    
    
        return null;
    }

    public void destroy() {
    
    
        System.out.println("destroy");
    }
}

我们可以对Servlet接口进行继承封装,来简化代码开发。

package com.xlr.web;

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

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

    }

    public ServletConfig getServletConfig() {
    
    
        return null;
    }

    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    
    
        //获取请求方式,根据不同的请求方式进行不同的业务处理
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        //1. 获取请求方式
        String method = request.getMethod();

        //2. 判断
        if ("GET".equals(method)) {
    
    
            // get方式处理逻辑
            doGet(request,servletResponse);
        } else if ("POST".equals(method)) {
    
    
            // get方式处理逻辑
            doPost(request,servletResponse);
        }
    }

    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请求的业务逻辑。

package com.xlr.web;

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

@WebServlet("/demo")
public class ServletDemo extends MyHttpServlet{
    
    

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

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

Servlet urlPattern配置

Servlet要想被访问,必须配置其访问路径(urlPattern)

一个Servlet可以配置多个urlPattern

@WebServlet(urlPatterns = {
    
    "/demo","/demo0"})

urlPattern配置规则:

  1. 精确匹配

    • 配置路径:@WebServlet("/demo5")
    • 访问路径:localhost:8030/web-demo/demo5
  2. 目录匹配

    • 配置路径:@WebServlet("/demo/*")

    • 访问路径:

      localhost:8030/web-demo/demo
      localhost:8030/web-demo/demo/abc
      localhost:8030/web-demo/demo/123
      localhost:8030/web-demo/demo/abc/123
      

      /*代表的是零或多个层级访问目录,同时精确匹配优先级要高于目录匹配。

  3. 拓展名匹配

    • 配置路径:@WebServlet("*.do")
    • 访问路径:
    localhost:8030/web-demo/abc.do
    localhost:8030/web-demo/123.do
    
    1. 如果路径配置的不是扩展名,那么在路径的前面就必须要加/否则会报错
    2. 如果路径配置的是*.do,那么在*.do的前面不能加/,否则会报错
  4. 任意匹配

    • 配置路径:

      @WebServlet("/")
      @WebServlet("/*")	
      
    • 访问路径:

      localhost:8030/web-demo/abc
      localhost:8030/web-demo/123
      

      当我们的项目中的Servlet配置了 “/”,会覆盖掉tomcat中的DefaultServlet

      会引发请求静态资源的时候没有走默认的而是走了自定义的Servlet类,如:localhost:8030/web-demo/a.html无法被访问到

      **DefaultServlet:**当其他的url-pattern都匹配不上时走这个Servlet

    优先级为 精确匹配 > 目录匹配 > 扩展名匹配 > /* > /

XML配置方式编写Servlet

Servlet从3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。

对于XML的配置步骤有两步:

  • 编写Servlet类

  • 在web.xml中配置该Servlet

    <web-app>
      <display-name>Archetype Created Web Application</display-name>
    
      <!--Servleet全类名-->
      <servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>com.xlr.web.ServletDemo</servlet-class>
      </servlet>
    
      <!--Servlet访问路径-->
      <servlet-mapping>
        <!-- servlet的名称,要和上面的名称一致-->
        <servlet-name>demo</servlet-name>
        <url-pattern>/demo</url-pattern>
      </servlet-mapping>
    
    </web-app>
    

猜你喜欢

转载自blog.csdn.net/m0_61465701/article/details/129644441
今日推荐