• Http&Servlet


    Http&Servlet

    一、HTTP协议介绍

    (一)HTTP概念

    Hypertext Transfer Protocol,HTTP超文本传输协议,是一个简单的请求-响应协议。
    规定了客户端和服务器之间 传输数据的一种格式

    (二)HTTP特点

    基于TCP/IP的高级协议
    默认端口号:80
    基于请求/响应模型:一次请求对应一次响应
    特点:
    1.简单快速。客户端向服务器请求服务时,只需要传送请求方法和路径。
    2.灵活。HTTP协议允许传送任意格式的数据。正在传输的类型由,content-type标明。
    3.无连接。就是每个请求都建立一个连接,请求处理完毕并发送至客户端之后就断开连接。这样明显有其缺点,就是在需要连续发送请求时,需要为每一个请求单独的再次建立连接,很浪费时间和资源。于是在HTTP协议1.1版本之后引入了可持续连接,也就是再每一个请求处理完毕后,它不会立刻就断开连接,而是再等待一段时间,如果在此期间又有新的请求过来,那么等待时间刷新,如果没有,则等待时间完毕后,连接关闭。
    4.无状态。是指协议对于每次请求的处理没有记忆能力,它不知道之前是否已经访问过,不保留访问痕迹。主要目的是为了保证数据传输的安全性。

    (三)传输数据的特点

    1、请求request

    请求分为三部分:
    请求行 : 请求行中,我们可以通过request对象的相应方法获取到比如协议名、服务名、端口号、项目名称、请求方式、参数列表等信息。
    请求头 : 请求头是当前对用户发送的数据的描述信息。请求头信息在请求的时候不需要程序员手动添加,是浏览器发送的时候已经处理好的。
    请求体 : 请求体就是请求中携带的数据,也就是我们需要获取的参数。

    2、响应response

    响应分为三部分:
    响应行 : 响应行中包含协议和版本
    响应头 : 服务器想要告诉浏览器 的一些信息。写法格式:头名称:值
    响应体 : 服务器响应给浏览器的源码信息

    二、Servlet详解

    (一)Servlet概念

    servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求

    image

    简单理解:
    我们之前讲的JDBC技术是用来实现Java语言和数据库之间的连接技术,而现在又涉及到Java和HTML进行连接,此时可以由HTML做前台,java做后台进行连接,这时候就需要一个中间件(Servlet)。

    (二)Servlet使用

    1、准备工作

    需求:写一个HTML页面将一个表单中的账号和密码传递到java类中并打印输出到控制台。

    image

    2、编写步骤
    编写步骤:
       1. 创建HTML页面并设计一个表单
       2. 创建一个普通类, 并继承HTTPServlet抽象类, 并重写Service方法
       3. 在web.xml文件中注册servlet, 作为前后台连接的中间件
       4. 修改前台表单中action的请求地址
       5. 通过浏览器输入对应的地址来访问测试
    
    3、实现方式
    • 创建HTML页面并设计一个表单
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <title>Title</title>
    </head>
    <body>
       <!-- 设计一个页面, 并设计表单 /项目名/访问地址 -->
       <form action="" method="post">
           <p>
               账号: <input type="text" name="username" id="username">
           </p>
           <p>
               密码: <input type="password" name="password" id="password">
           </p>
           <p>
               <input type="submit" value="登录">
           </p>
       </form>
    </body>
    </html>
    
    • 创建一个普通类, 并继承HTTPServlet抽象类, 并重写Service方法
    package com.ujiuye.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServlet;
    import java.io.IOException;
    
    //创建一个普通类, 让其普通类继承HttpServlet抽象类
    public class LoginServlet extends HttpServlet {
       //并重写Service方法
       @Override
       protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           String username = request.getParameter("username");
           String password = request.getParameter("password");
           System.out.println("账号为: " + username + " ==> 密码为: " + password);
       }
    }
    
    • 在web.xml文件中注册servlet, 作为前后台连接的中间件
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
              version="3.0">
    
       <!--注册servlet-->
       <servlet>
           <servlet-name>login</servlet-name><!--servlet名称-->
           <servlet-class>com.ujiuye.servlet.LoginServlet</servlet-class><!--全路径-->
       </servlet>
       <!--映射路径/虚拟路径-->
       <servlet-mapping>
           <servlet-name>login</servlet-name><!--servlet名称-->
           <url-pattern>/login</url-pattern><!--访问路径, 以 / 开头-->
       </servlet-mapping>
    </web-app>
    
    • 修改前台表单中action的请求地址
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <title>Title</title>
    </head>
    <body>
       <!-- 设计一个页面, 并设计表单 /项目名/访问地址 -->
       <form action="login" method="post">
           <p>
               账号: <input type="text" name="username" id="username">
           </p>
           <p>
               密码: <input type="password" name="password" id="password">
           </p>
           <p>
               <input type="submit" value="登录">
           </p>
       </form>
    </body>
    </html>
    
    • 通过浏览器输入对应的地址来访问测试

    image

    效果展示:

    image

    (三)Servlet原理

    实现原理:
    ① 当服务器接收到客户端浏览器的请求后,先解析请求的url路径,获取访问Servelt的资源路径
    ② 查找项目的web.xml,根据资源路径匹配web.xml中的 <servlet-mapping>中的<url-pattern> 
    ③ 如果没有匹配到报 404 如果匹配到了 根据<servlet-mapping>中的<servlet-name> 
    ④ 再去匹配 <servlet>中的<servlet-name> 如果没有匹配到 404 
    ⑤ 如果匹配到了执行<servlet> 中的<servlet-class> 从而以反射的方式访问到指定的Servlet,调用其方法
    

    (四) Servlet生命周期

    servlet生命周期:从创建到销毁的全过程。共分为三个阶段:
       1、初始化
       2、使用(提供服务)
       3、销毁
    

    案例演示:

    • 创建一个Servlet重写其内部的三个方法init()、service()、destroy()
    package com.ujiuye.servlet;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class LifeCycleServlet implements Servlet {
       //初始化
       @Override
       public void init(ServletConfig servletConfig) throws ServletException {
           System.out.println("servlet初始化了...");
       }
    
       @Override
       public ServletConfig getServletConfig() {
           return null;
       }
    
       //服务
       @Override
       public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
           System.out.println("servlet中的service方法执行了....");
       }
    
       @Override
       public String getServletInfo() {
           return null;
       }
    
       //销毁
       @Override
       public void destroy() {
           System.out.println("servlet销毁了...");
       }
    }
    
    • 在web.xml文件中注册Servlet
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
              version="3.0">
    
       <!--注册servlet-->
       <servlet>
           <servlet-name>lifeCycle</servlet-name><!--servlet名称-->
           <servlet-class>com.ujiuye.servlet.LifeCycleServlet</servlet-class><!--全路径-->
       </servlet>
       <!--映射路径/虚拟路径-->
       <servlet-mapping>
           <servlet-name>lifeCycle</servlet-name><!--servlet名称-->
           <url-pattern>/lifeCycle</url-pattern><!--访问路径, 以 / 开头-->
       </servlet-mapping>
    </web-app>
    
    • 测试查看Servlet生命周期

    当我们启动tomcat服务器时,观察控制台并无打印消息,表示Servlet默认情况下在启动服务器时并未被创建。在浏览器地址栏中直接输入MyServlet的虚拟访问地址:
    http://localhost:8080/day10_servlet/lifeCycle
    此时观察控制台打印输出初始化与服务的相关信息,当多次访问该地址,发现服务方法被多次调用执行。

    image

    当我们关闭tomcat服务,会在控制台打印销毁方法的信息。

    image

    通过以上案例发现Servlet默认情况下是在第一次访问时被创建并初始化的,为了减少内存的压力,我们可否改变它的创建时机呢?
    答案是肯定的。我们可以在web.xml文件中进行配置,使得Servlet在服务器启动时直接创建并初始化。
    load-on-startup节点必须写在servlet节点的内部,且作为最后一个节点。取值必须是整数,如果是大于等于0的整数表示在服务器启动时就被创建并初始化,如果有多个Servlet设置了load-on-startup节点的值,那么值越小越优先执行;如果是负数则表示第一次被访问时创建并初始化,也就是默认情况,可以省略不写。

    image

    总结:
    1、init()初始化阶段:默情况当第一次访问Servlet时,Servlet容器(tomcat)会加载Servlet,加载完成后,Servlet容器(tomcat)会创建一个Servlet实例并调用init()方法进行初始化;如果需要改变创建时机,只需要在web.xml文件中配置load-on-startup节点值为大于等于0的整数即可。init()方法只会执行一次,也说明一个Servlet只有一个实例,即单例模式。
    2、service()服务阶段:当Servlet每被访问一次,service方法就会自动被调用一次,所以该方法可执行多次。
    3、Destroy()销毁阶段:当关闭服务或资源重新加载时,destroy方法会被执行,这就标识着整个Servlet的生命周期到此结束。该方法仅被执行一次。

    只执行一次的阶段有 初始化阶段、销毁阶段。 因此 Servlet是单例的。
    执行多次的阶段 服务阶段

    初始化的时机可以选择 (1.用到的时候再初始化 2.启动项目自动初始化)

    5)Servlet路径多元化

    问题 :  一个Servlet是否可以配置多个访问路径?  答案是可以的
    url-pattern配置方式共有三种:
    	1. 完全路径匹配(一层路径/指定多层路径) :以 / 开始				
    	例如:	 /hello ,  /hello1,  /aa/hello2
    	2. 目录匹配(多种路径都可以访问 排除已经指定的路径) :以 / 开始 需要以 * 结束.	
    	例如: 	/*(所有),  /aaa/* (aaa目录下的所有),  /aaa/bbb/*
    	3. 扩展名匹配(后缀名) :不能以 / 开始 以 * 开始的. 
    	例如:  *.do ,  *.action		注意: 错误的写法 : /*.do
    

    案例演示

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
              version="3.0">
    
       <!--注册servlet-->
       <servlet>
           <servlet-name>hello</servlet-name><!--servlet名称-->
           <servlet-class>com.ujiuye.servlet.HelloServlet</servlet-class><!--全路径-->
       </servlet>
       <!--映射路径/虚拟路径-->
       <servlet-mapping>
           <servlet-name>hello</servlet-name><!--servlet名称-->
           <url-pattern>/hello</url-pattern><!--访问路径, 以 / 开头-->
           <!-- 目录匹配 -->
           <url-pattern>/aa/bb/cc</url-pattern>
           <url-pattern>/aa/bb/cc/dd/*</url-pattern>
           <!-- 扩展名匹配 -->
           <url-pattern>*.do</url-pattern>
           <url-pattern>*.action</url-pattern>
       </servlet-mapping>
    </web-app>
    

    6)Servlet注解方式的使用

    Java 注解(Annotation)又称 Java 标注,是 JDK1.5 引入的新特性。其主要作用是简化复杂的编码工作。Java 语言中的类、方法、变量、参数和包等都可以被标注,被标注的元素就具有了一些特定的功能。
    Servlet的注解(@WebServlet)是Servlet3.0及以上版本支持的,主要目的是简化web.xml配置。
       
    因此配置Servlet的方式有两种:
       1.web.xml中配置 Servlet  这种写法比较麻烦。 代码比较多
       2.通过注解 @WebServlet,配置了注解就不需要在web.xml中配置.
       
    /*注意  每一个Servlet只能选择其中一种方式配置 *
       
    

    案例演示:

    package com.ujiuye.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /*此注解配置相当于web.xml文件中url-pattern设置的访问路径*/
    @WebServlet("/hello")
    public class HelloServlet extends HttpServlet {
    
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      System.out.println("注解版Servlet更加简明");
    }
    }
    

    注意事项:

    注意:一个Servlet的配置可以使用注解,也可以使用web.xml文件,但二者不能共存,只能任选其一,否则会报错。

  • 相关阅读:
    零基础转IT,我推荐你学习这三门技术
    蜗牛学院行内人分析:参加IT培训,大家一定要注意这五点!
    蜗牛学院分析:Web前端开发的就业前景怎么样,薪资待遇如何?
    软件测试和测试开发有什么区别?
    转行者越来越多,程序员是不是不值钱了呢?
    蜗牛学院卿老师:Python中几个比较容易混淆的概念解释
    webpack4.x的css单独打包、合并、自动添加前缀、压缩
    webpack4的splitChunksPlugin配置参数详解---代码分割 、懒加载以及prefetching 和 preloading
    vue列表页进入详情页,返回列表项不刷新
    js数组去重
  • 原文地址:https://www.cnblogs.com/conglingkaishi/p/15255706.html
Copyright © 2020-2023  润新知