JavaWeb-HTTP协议(服务器数据的接收、处理、响应流程)详解

HTTP协议

● 什么是HTTP协议? 超文本传输协议(Hypertext Transfer Protocol)服务器传输超文本到本地浏览器的传送协议,是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程

● HTTP是基于TCP/IP通信协议来传送数据

● HTTP是属于引用层的协议,由于棋简捷、快速的方式、适用于分布式超媒体信息系统

HTTP请求

客户端连上服务器后,向服务器请求某个web资源,称之为客户端向服务器发送一个http请求。

就是从浏览器中以超链接,表单等向服务器发送的请求都称为http请求。

请求包括:请求行,请求头,(这两部分会自动发送) 请求体。

请求行:http请求方式,请求资源名称,http版本(例如post、post、text.jsp、HTTP/1.1)

请求头:服务器端和客户端的一些信息格式为键值对。

请求体:是指表单post方式请求时,向服务器端发送的数据

请求头包含主机地址,以及客户端的一些环境信息,以键值对的形 式传递.

Host: 127.0.0.1:8088 请求的主机地址
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 浏览器能够处理的内容类型
Accept-Encoding: gzip, deflate, br 浏览器能够处理的压缩编码
Accept-Language: zh-CN,zh;q=0.9 浏览器当前设置的语言
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 使用的浏览器和操作平台信息
Connection: keep-alive 浏览器与服务器之间连接的类型

请求体代表着浏览器在post请求方式中传递给服务器的参数,请求体中参数以 键值形式传递, 多个用&链接,服务器接收到后再解析. username=admin&userpwd=123

两种HTTP请求方式

get(获得):从服务器端获取数据,在地址栏会显示发送的数据,但是一般有以下状况
1、不安全
2、传输的数据大小受限制 一般浏览器的大小为2-5kb
● 以超链接访问,默认是GET方式
● form提交,不指定method,默认为GET方式

post(发送):向服务器端发送数据,向服务器端发送数据,发送的数据是在请求体当中,安全(相对安全),大小不受限制
● form提交,指定method=“post”

get/post的区别

● get方式主要是从服务器获取信息;post主要是向服务器提交信息
● get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据是放置在请求体中提交。
● get方式提交的数据大小受限制一般都很小(不同浏览器也会有不同);而 post则没有此限制。

在父类的service中写了一个判断 get---->doGet、post----->doPost
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我的第一个web程序</title>
</head>
<body>
<a href="demourl">列表</a>
<form action="demourl" method="post">
    账号:<input type="text">
    密码:<input type="password">
    <input type="submit" value="保存">
</form>
</body>
</html>

<?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>demo</servlet-name>
        <servlet-class>com.student.firstweb.servlet.Demo1Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/demourl</url-pattern>
        <!--前端点击的连接就是与这个做连接相对应-->
    </servlet-mapping>
</web-app>

package com.student.firstweb.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo1Servlet extends HttpServlet {
    //service 每次请求都要调用,由于http请求分为get,post请求,在service中两者处理上有略微不同
    //所以父类中定义了doGet()  doPost()分别处理get,post请求

    //就是在父类service的方法中写了一个判断 get就调用doGet(),post就调用doPost()

    //doGet()和doPost()都是属于service中的方法。
    //doGet()处理get请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet方法");
    }

    //doPost()处理post请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost方法");
    }
}


分别点击列表和保存就调用了各自的请求方式
列表—>doGet、保存—>doPost
在这里插入图片描述

在服务器接收信息(HttpServletRequest)

● 请求和响应是Web交互最基本的模式,在Servlet中,用HttpServletRequest 来表示请求。

(HttpServletRequest req, HttpServletResponse resp)中的HttpServletReuuest req

● HttpServletRequest是ServletRequest的子接口。HttpServletRequest比ServletRequest多了一些针对于Http协议的方法。

数据请求先到达服务器,服务器接收请求数据,然后服务器将接收到的数据封装到RequestFacade(这里说明的这个类属于Tomcat),而他实现的是java对外提供的HttpServletRequest接口 (是RequestFacade implements HttpServletRequest) ,所以程序员只要面对HttpServletRequest req,服务器就会把接收到的数据传输过来(例如:Tomcat就将它自己RequestFacade这个类给传输过来)

所以我们在写代码的时候只需要写一个HttpServletRequest,但实际上传输过来的是RequestFacade

所以我们就只需要学习java中的统一标准接口。
这就是javaSE多态的体现

● HttpServletRequest :封装了请求的信息,可以从中获取任何请求信息。

请求行

获得请求类型数据: req.getMethod()
获得协议:req.getProtocol()
获得请求服务器的地址:req.getServerName()
获得请求服务器的端口:req.getServerPort()

请求头

获得客户端的ip:req.getRemoteAddr()
获得客户端的端口:req.getServerPort()
获得请求头中的某一数据:req.getHeader(“User-Agent”)

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我的第一个web程序</title>
</head>
<body>
<!--前段传输的数据一定都是键=值&键=值-->
<a href="demourl?name=张三&age=20">列表</a>
</body>
</html>

<?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>demo</servlet-name>
        <servlet-class>com.student.firstweb.servlet.Demo1Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/demourl</url-pattern>
        <!--前端点击的连接就是与这个做连接相对应-->
    </servlet-mapping>
</web-app>

package com.student.firstweb.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Demo1Servlet extends HttpServlet {
    //service 每次请求都要调用,由于http请求分为get,post请求,在service中两者处理上有略微不同
    //所以父类中定义了doGet()  doPost()分别处理get,post请求

    //就是在父类service的方法中写了一个判断 get就调用doGet(),post就调用doPost()

    //doGet()和doPost()都是属于service中的方法。
    //doGet()处理get请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet方法");
        //请求行数据
        System.out.println(req.getMethod());//获得请求类型数据
        System.out.println(req.getProtocol());//获得协议
        System.out.println(req.getServerName());//获得请求服务器的地址
        System.out.println(req.getServerPort());//获得请求服务器的端口

        //请求头数据
        System.out.println(req.getRemoteAddr());//获得客户端的ip
        System.out.println(req.getServerPort());//获得客户端的端口
        System.out.println(req.getHeader("User-Agent"));//获得请求头中的某一数据
     }
}

在这里插入图片描述

请求体

接收用户的请求数据,因为前段传输过来的数据都是键值对,所以后端就可以通过键来接收前端传输过来的数据。

通过parameter来获取前段发送过来的数据

getParameter(name) — String 通过name获得值
getParameterValues — String[ ] 通过name获得多值
req.getParameter(“name”)

Tomcat8.0之后get请求数据的解码方式支持中文 ,但是post请求解码是不支持中文的,所以我们要设置post请求数据的解码格式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我的第一个web程序</title>
</head>
<body>
<!--前段传输的数据一定都是键=值&键=值-->
<a href="demourl?name=张三&age=20">列表</a>
<form action="demourl" method="post">
    账号:<input type="text" name="account">
    密码:<input type="password" name="password">
    课程:<input type="checkbox" value="java" name="course">java
    <input type="checkbox" value="c" name="course">c
    <input type="checkbox" value="python" name="course">python
    <input type="submit" value="保存">
</form>
</body>
</html>

<?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>demo</servlet-name>
        <servlet-class>com.student.firstweb.servlet.Demo1Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/demourl</url-pattern>
        <!--前端点击的连接就是与这个做连接相对应-->
    </servlet-mapping>
</web-app>

package com.student.firstweb.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

public class Demo1Servlet extends HttpServlet {
    //service 每次请求都要调用,由于http请求分为get,post请求,在service中两者处理上有略微不同
    //所以父类中定义了doGet()  doPost()分别处理get,post请求

    //就是在父类service的方法中写了一个判断 get就调用doGet(),post就调用doPost()

    //doGet()和doPost()都是属于service中的方法。
    //doGet()处理get请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet方法");

        //接收用户请求的数据,通过键名来获得前段的数据
        // Tomcat8.0之后get请求数据的解码方式支持中文
        String name = req.getParameter("name");
        System.out.println(name);
        System.out.println(req.getParameter("age"));
    }

    //doPost()处理post请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost方法");

        //因为不支持中文,所以就要设置中文编码
        req.setCharacterEncoding("utf-8");//设置post请求数据的解码格式
        System.out.println(req.getParameter("account"));
        System.out.println(req.getParameter("password"));
        System.out.println(req.getParameter("course"));
        String[] courses = req.getParameterValues("course");
        System.out.println(Arrays.toString(courses));
    }
}

在这里插入图片描述

处理

例如:使用jdbc处理

响应

一个http响应代表服务器向客户端回送的数据,它包括:响应行,响应头,响应体。
响应行里包含了http协议版本,以及用于描述服务器对请求的处理结果。

HTTP/1.1 (协议版本) 200(状态吗) OK(状态码描述)

状态码就是:服务器和浏览器用于确定状态的固定数字号码(实现固定好的)

◆ 200:请求成功
◆ 302:请求重定向
◆ 400:语义有误,当前请求无法被服务器理解或请求参数有误
◆ 404:请求资源不存在,通常是路径写错了或者服务器资源删除了
◆ 500:服务内部错误(代码异常)

响应头就是用于描述服务器的基本信息,以及数据描述
Ser ver Apache-Coyote/1.1
Content-Type text /html;charset=UTF-8
Content-Length 0
Date Wed, 13 Sep 2017 02:26:07 GMT

响应体则代表服务器向客户端浏览器回送的正文

(HttpServletRequest req, HttpServletResponse resp)中的HttpServletResponse resp

就是根据处理的结构向客户端做出响应

也是一个接口,是和接收同理。Tomcat实现出java中的一个接口==(ResponseFacade implements HttpServletResponse)==,我们利用多态的性质通过java的接口来调用我们需要的方法 。

 //响应
        PrintWriter writer = null;
        try{
            resp.setContentType("text/html;charset=utf-8");//设置响应内容的编码格式
            writer = resp.getWriter();//获得打印字符流
            writer.println("<h1>操作成功<h1>");
        }catch (Exception e){
            e.printStackTrace();
            writer.println("<h1>服务器忙<h1>");
        }

是写在servlet中,响应回去我们所需要的动态页面内容

早期的时候是用jsp来书写需要返回的动态页面,但是到现在它已经被淘汰了,因为18年出了ajax,几乎已经完全替换了jsp的书写

使用ajax从前端向后端进行发起请求交互