Http协议&Servlet

Http协议&Servlet

1.Http协议

  • 什么是http协议

    针对网络上的客户端与服务器端在执行http请求的时候,遵守的一种规范。 其实就是规定了客户端在访问服务器端的时候,要带上哪些东西,服务器端返回数据的时候,也要带上什么东西。

  • 版本

    1.0

    请求数据,服务器返回后, 将会断开连接。

    2.0

    请求数据,服务器返回后, 连接还会保持着。 除非服务器 | 客户端关掉。 有一定的时间限制,如果都空着这个连接,那么后面会自己断掉。

2.演示客户端如何与服务器端通讯

步骤:

  1. 安装抓包工具HttpWatch(我装到了firefox中)

  2. 打开tomcat,输入localhost:8080打开首页

  3. examples-->Servlet examples-->找到Request Parameters,点击Execute,如下图,输入参数,先点Record,再点提交查询

    Http协议&Servlet

  4. 请求细节如下图:

    左边为请求数据,右边为响应数据。

    Http协议&Servlet

  • Http请求数据

    请求的数据里面包含三个部分内容 : 请求行 、 请求头 、请求体。

    • 请求行

      POST /examples/servlets/servlet/RequestParamExample HTTP/1.1
      

      POST:请求方式 ,以post去提交数据
      /examples/servlets/servlet/RequestParamExample:请求的地址路径,就是要访问哪个地方

      HTTP/1.1:协议版本

    • 请求头

      Host: localhost:8080
      User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
      Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
      Accept-Encoding: gzip, deflate
      Referer: http://localhost:8080/examples/servlets/servlet/RequestParamExample
      Connection: keep-alive
      Content-Type: application/x-www-form-urlencoded
      Content-Length: 38
      

      Host:主机地址

      User-Agent:用户代理,向服务器表明当前来访的客户端信息

      Accept:客户端向服务器端表明,我能支持什么类型的数据

      Accept-Language:支持语言格式

      Accept-Encoding:支持的编码类型

      Referer:真正请求的地址路径,全路径

      Connection:keep-alive:保持连接

      Content-Type:提交的数据类型

      Content-Length:数据长度

    • 请求体

      firstname=%E7%8E%8B&lastname=%E4%BA%8C
      

      浏览器真正发送给服务器的数据,发送的数据是key=value形式,如果存在多个数据,则使用&连接。

  • Http响应数据

    响应的数据里面包含三个部分内容 : 响应行 、 响应头 、响应体。

    HTTP/1.1 200 
    Content-Type: text/html;charset=UTF-8
    Content-Length: 675
    Date: Sat, 17 Oct 2020 02:45:10 GMT
    <!DOCTYPE html><html>
    	...这里还有很多数据...
    </html>
    
    • 响应行

      HTTP/1.1 200 
      

      协议版本

      状态码

      交互结果状态码:
      200:成功,正常处理,得到数据。
      403:for bidden,拒绝
      404:Not Found
      500:服务器异常

    • 响应头

      Content-Type: text/html;charset=UTF-8
      Content-Length: 675
      Date: Sat, 17 Oct 2020 02:45:10 GMT
      

      Content-Type :服务器返回给客户端的内容类型

      Content-Length :返回的数据长度

      Date :响应的时间

    • 响应体

      <!DOCTYPE html><html>
      	...这里还有很多数据...
      </html>
      

3.Get和Post请求

看请求行是Get还是Post即可区分是Get请求还是Post请求。

Http协议&Servlet

  • post

    1. 数据是以流的方式写过去,不会在地址栏上面显示。现在一般提交数据到服务器使用的都是POST。
    2. 以流的方式写数据,数据没有大小限制。
  • get

    1. 会在地址栏后面拼接数据,所以有安全隐患。 一般从服务器获取数据,并且客户端也不用提交上面数据的时候,可以使用GET。
    2. 能够带的数据有限,1kb大小。

4.Web资源

在http协议当中,规定了请求和响应双方,客户端和服务器端。与web相关的资源。

有两种分类:

  • 静态资源

    html 、 js、 css

  • 动态资源

    servlet/jsp

5.Servlet

servlet其实就是一个java程序,运行在web服务器上,用于接收和响应客户端的http请求。 更多的是配合动态资源来做,当然静态资源也需要使用到servlet,只不过是Tomcat里面已经定义好了一个DefaultServlet。

5.1HelloServlet

  1. idea集成tomcat,编写一个web模块或工程

    Http协议&Servlet

  2. 新建HelloServlet类,实现Servlet接口

    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() {
        }
    }
    
    1. 在web/WEB-INF/web.xml中配置HelloServlet
        <!--向tomcat注册servlet,名为HelloServlet,路径为com.itheima.test.HelloServlet-->
        <servlet>
            <servlet-name>HelloServlet</servlet-name>
            <servlet-class>com.itheima.test.HelloServlet</servlet-class>
        </servlet>
        <!--注册servlet的映射,servlet-name与上面注册的一致,url-pattern为浏览器地址栏访问的path,以/打头-->
        <servlet-mapping>
            <servlet-name>HelloServlet</servlet-name>
            <url-pattern>/a</url-pattern>
        </servlet-mapping>
    

5.3Servlet执行过程

以HelloServlet为例:

浏览器地址栏url:http://localhost:8080/Demo1/a

  1. 通过localhost:8080找到tomcat应用,找到Demo1项目
  2. 找web.xml,在里面找url-pattern,看哪一个里的内容为/a
  3. 找到servlet-mapping中的servlet-name
  4. 从而找到servlet中的servlet-name,然后是servlet-class
  5. 然后创建该类的实例,继而执行该servlet中的service方法

5.4Servlet通用写法

定义一个类,继承HttpServlet,覆写doGet和doPost方法,一般不再覆写service方法。

public class HelloServlet2 extends HttpServlet {
    //处理get请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
    //处理post请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

5.5Servlet生命周期

  • 生命周期

从创建到销毁的一段时间

  • 生命周期方法

从创建到销毁所调用的方法

  • init方法

    在创建该servlet的实例时,就执行该方法。一个servlet只会初始化一次, init方法只会执行一次。默认情况下是:初次访问该servlet,才会创建实例。

  • service方法

    只要客户端来了一个请求,那么就执行这个方法。该方法可以被执行很多次。 一次请求,对应一次service方法的调用。

  • destroy方法

    servlet销毁的时候执行该方法。

    1. 该项目从tomcat的里面移除。
    2. 正常关闭tomcat就会执行 shutdown.bat

doGet 和 doPost不算生命周期方法,所谓的生命周期方法是指,从对象的创建到销毁一定会执行的方法, 但是这两个方法,不一定会执行。

5.6让Servlet创建实例的时机提前

  1. 默认情况下,只有在初次访问servlet的时候,才会执行init方法。 有的时候,我们可能需要在这个方法里面执行一些初始化工作,或做一些比较耗时的逻辑。;

  2. 那么这个时候,初次访问,可能会在init方法中逗留太久;

  3. 在配置的时候, 使用load-on-startup元素来指定, 给定的数字越小,启动的时机就越早,一般不写负数,从2开始即可。

    HelloServlet2com.itheima.test.HelloServlet22

5.7ServletConfig

servlet的配置对象,可以获取servlet在配置的时候的一些信息。

public class HelloServlet2 extends HttpServlet {
    //处理get请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.得到servlet配置对象ServletConfig,用于配置servlet的信息
        ServletConfig config=getServletConfig();
        String servletName=config.getServletName();//获取配置servlet的servlet-name的内容
        System.out.println(servletName);
        //2.获取指定初始化参数
        String address = config.getInitParameter("address");
        System.out.println(address);
        //3.获取所有初始化参数
        Enumeration<String> initParameterNames = config.getInitParameterNames();
        while (initParameterNames.hasMoreElements()){
            String key = initParameterNames.nextElement();
            String value = config.getInitParameter(key);
            System.out.println(key+"="+value);
        }
    }
    //处理post请求
    //可以设置来了post请求也去执行doGet方法
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
  • web.xml
<servlet>
        <servlet-name>HelloServlet2</servlet-name>
        <servlet-class>com.itheima.test.HelloServlet2</servlet-class>
        <init-param>
            <param-name>address</param-name>
            <param-value>河南</param-value>
        </init-param>
        <init-param>
            <param-name>city</param-name>
            <param-value>驻马店</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet2</servlet-name>
        <url-pattern>/b</url-pattern>
    </servlet-mapping>
  • 为什么需要有ServletConfig

    1. 在开发中使用到了一些技术,或者一些代码,我们不会,但是有人写出来了,它的代码放置在了自己的servlet类里面;

    2. 刚好这个servlet 里面需要一个变量值,但是这个值不能是固定的,所以要求使用到这个servlet的公司,在注册servlet的时候,必须要在web.xml里面,声明init-params。在开发当中比较少用。