第2阶段 第12讲 XML&HTTP协议

课程回顾

  • 如何创建一个Servlet
  • 如何配置Servlet
  • Servlet生命周期
  • Servlet源码解析

XML解析

xml简介

Extensible Markup Language 中文: 可扩展标记语言

可扩展标记语言标准通用标记语言的子集,简称XML。是一种用于标记电子文件使其具有结构性的标记语言。 在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。早在1998年,W3C就发布了XML1.0规范,使用它来简化Internet的文档信息传输

不同的系统之间如何进行数据传输,JAVA写的系统如何把数据传递给.Net系统或者PHP系统;反之亦然。我们就需要一个可以跨各种技术平台的一种数据传递格式;不依赖于具体的技术。这就是XML技术,不依赖于底层技术,仅仅传递数据。

xml语法

1、必须有声明语句。

<?xml version="1.0" encoding="UTF-8"?>

2、注意大小写,区分大小写

3、XML文档有且只有一个根元素

4、属性值使用引号

5、所有的标记必须有相应的结束标记

6、所有的空标记也必须被关闭

xml节点类型

  • 元素节点 element
  • 属性节点 attribute
  • 文本节点 text
  • 注释节点 comment

xml和对象的转换

我们编程是面向对象的编程,所有数据都是以对象的方式传输, 问题:

  • 把java对象转换成XML文件
  • 把XML文件解析成java对象

譬如: 调用别的系统返回的数据是XML格式的

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <status>200</status>
    <mchuid>100</mchuid>
    <mchmid>100</mchmid>
    <userid>50</userid>
    <msg>信息正确,授权成功</msg>
</response>

xml解析的主流技术

广义的解析包括: 把对象转换成XML文件、创建XML文件、修改XML文件、删除XML文件节点、把XML转换成对象

主流的XML文件解析技术:

  • DOM解析: W3C的官方标准, 以层次结构(类似于树型)来组织节点和信息片段,
  • SAX(Simple API for XML)解析:通过事件驱动,每发现一个节点就引发一个事件,事件推给事件处理器
  • DOM4J((Document Object Model for Java))解析:简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP
  • JDOM(Java-based Document Object Model)解析:Java特定的文档对象模型。自身不包含解析器,使用SAX
  • StAX(Streaming API for XML) 解析: 流模型中的拉模型分析方式。提供基于指针和基于迭代器两种方式的支持

DOM4解析XML文件

使用DOM4J操作XML文件

<?xml version="1.0" encoding="UTF-8"?>
<phoneInfo> 
  <brand name="小米" id="1001"> 
    <type name="小米8"/>  
    <type name="小米9"/>  
    <type name="小米MIX"/> 
  </brand>  
  <brand name="iphone" id="1002"> 
    <type name="iphoneX"/>  
    <type name="iphoneXs"/>  
    <type name="iphone8">xxx</type> 
  </brand>  
  <brand name="华为" id="1003"> 
    <type name="p20"/>  
    <type name="p30"/>  
    <type name="P30pro"/> 
  </brand> 
</phoneInfo>

案例:

package com.ujiuye.xml;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
public class XMLTest {
	@Test
	public void deleteElement() throws Exception{
		//1.创建解析器对象
		SAXReader reader = new SAXReader();
		//2.读取XML文件
		Document document = reader.read(new File("src/info.xml"));
		//3.获取根节点
		Element rootEle = document.getRootElement();
		//4.获取所有的子节点
		Iterator<?> it =  rootEle.elementIterator();
		while(it.hasNext()) {
			Element element = (Element) it.next();
			if(element.attributeValue("name").equals("魅族")) {
				element.getParent().remove(element);
			}
		}
		//5.写到文件
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/info.xml"), OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.flush();
		writer.close();
	}
	
	
	@Test
	public void updateElement() throws Exception{
		//1.创建解析器对象
		SAXReader reader = new SAXReader();
		//2.读取XML文件
		Document document = reader.read(new File("src/info.xml"));
		//3.获取根节点
		Element rootEle = document.getRootElement();
		//4.获取所有的子节点
		Iterator<?> it =  rootEle.elementIterator();
		while(it.hasNext()) {
			Element element  =(Element) it.next();
			if(element.attributeValue("name").equals("魅族")) {
				Iterator<?> it2 = element.elementIterator();
				while(it2.hasNext()) {
					Element eleType = (Element) it2.next();
					if(eleType.attributeValue("name").equals("魅族17pro")) {
						eleType.addAttribute("name", "华为P30");
					}
				}
			}
		}
		
		//把文档写到文件
		OutputStream os = new FileOutputStream("src/info.xml");
		XMLWriter writer = new XMLWriter(os,OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.flush();
		writer.close();
	}
	
	@Test
	public void addElement() throws Exception{
		//1.创建解析器对象
		SAXReader reader = new SAXReader();
		//2.读取XML文件
		Document document = reader.read(new File("src/info.xml"));
		//3.获取根节点
		Element rootEle = document.getRootElement();
		//4.添加子节点
		Element childEle = rootEle.addElement("brand");
		//5.给子节点添加属性
		childEle.addAttribute("name", "魅族");
		//6.给子节点添加节点
		Element typeEle = childEle.addElement("type");
		typeEle.addAttribute("name", "魅族17pro");
		
		//把文档写到文件
		OutputStream os = new FileOutputStream("src/info.xml");
		XMLWriter writer = new XMLWriter(os,OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.flush();
		writer.close();
	}
	@Test
	public void parseXMl() throws Exception{
		//1.创建解析器对象
		SAXReader reader = new SAXReader();
		//2.读取xml文件
		Document document = reader.read(new File("src/info.xml"));
		//3.获取根节点
		Element rootEle = document.getRootElement();
		System.out.println("根节点名称:"+rootEle.getName());
		//4.获取所有的字节点
		Iterator<?> it = rootEle.elementIterator();
		//5.遍历所有的子节点
		while(it.hasNext()) {
			Element element = (Element) it.next();
			System.out.println("子节点名称:"+element.getName());
			System.out.print("\tname:"+element.attributeValue("name"));
			System.out.print("\tid:"+element.attributeValue("id"));
			System.out.println();
			//再获取子节点
			Iterator<?> it2 = element.elementIterator();
			while(it2.hasNext()) {
				Element ele2 = (Element) it2.next();
				System.out.println("\n节点名称:"+ele2.getName() );
				System.out.print("属性:"+ele2.attributeValue("name"));
			}
		}
	}	
}

把一组对象写入XML文件

实体类:

package com.ujiuye.xml;

public class Emp {

	private int id;
	private String name;
	private int age;
	private String gender;
	private int salary;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public int getSalary() {
		return salary;
	}
	public void setSalary(int salary) {
		this.salary = salary;
	}
	public Emp(int id, String name, int age, String gender, int salary) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.salary = salary;
	}
}

写入文件:

public static void main(String[] args) {
		List<Emp> list = new ArrayList<Emp>();
		list.add(new Emp(1, "jack", 33, "男", 5000));
		list.add(new Emp(2, "boss", 55, "男", 55000));
		list.add(new Emp(3, "marry", 22, "女", 3500));
		list.add(new Emp(4, "kate", 25, "女", 6000));
		list.add(new Emp(5, "tom", 32, "男", 8500));

		/*
		 * 生成一个xml的基本步骤 
		 * 1:创建文档对象Document 
		 * 2:为Document添加根节点 
		 * 3:为根节点组建树状结构 
		 * 4:创建XMLWriter
		 * 5:为XMLWriter指定写出目标 
		 * 6:写出xml
		 */
		// 1.通过DocumentHelper创建Document对象
		Document doc = DocumentHelper.createDocument();
		/*
		 * 2.Document的方法 Element addElement(String name) 该方法用于向文档中添加给定名字的根元素,
		 * 返回的Element实例就表示该 根元素 需要注意的是,该方法只能调用一次。 调用第二次会抛出异常。
		 */
		Element root = doc.addElement("list");
		//循环添加每一个员工信息
		for (Emp e : list) {
			// 向根标签中添加emp标签
			Element emp = root.addElement("emp");
			// 向emp标签中添加子标签name
			Element name = emp.addElement("name");
			name.addText(e.getName());
			// 向emp标签中添加子标签age
			emp.addElement("age").addText(e.getAge() + "");
			emp.addElement("gender").addText(e.getGender());
			emp.addElement("salary").addText(e.getSalary() + "");
			/*
			 * 为标签添加属性 Element addAttribute( String name,String value ) 为当前标签添加给定名字以及对应值的属性
			 * 返回值仍然为当前标签。这样做的目的是可以连续添加若干属性 就好像StringBuilder的append的 返回值效果和作用。
			 */
			emp.addAttribute("id", e.getId() + "");
		}

		//当退出循环后,那么Document中的 结构就已经构建完了 需要将其写出为xml
		try {
			XMLWriter writer = new XMLWriter(new FileOutputStream("src/emp.xml"), OutputFormat.createPrettyPrint());
			//将Document对象写出到文件中 这时会将Document转换为xml格式 写入文件。
			writer.write(doc);
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

DOM4J和XPath

刚才在DOM4J解析XML文件的时候,问题是我们要遍历所有的节点,然后再判断找到需要的节点进行操作。能不能直接定位到某个节点而不是遍历。这就是XPath的功能: xml path根据节点路径获取节点。

XPath: XPath 是xml的路径语言,使用路径表达式来操作xml文档,使用XPath操作xml文档更加便捷。
使用XPath,我们还需要导入一个依赖包,https://mvnrepository.com/artifact/jaxen/jaxen/1.1.6

1.XPath的基本使用

dom4j提供了两个方法支持XPath搜索:

  • List selectNodes(String expr); 获取多个节点

  • Node selectSingleNode(String expr); 获取单个节点

我们首先还是获取Document对象,因为以上两个搜索方法都是Document的方法。

2.Xpath表达式的几种写法

第一种形式:
/AAA/BBB/CCC:表示层级结构,表示AAA下面BBB下面的所有CCC
第二种形式:
//BBB:选择文档中所有的BBB元素
第三种形式:
/AAA/BBB/:选择目录下的所有元素
/
///BBB:选择有三个祖先元素的BBB元素
//*:选择所有的元素
第四种形式:
//AAA[1]/BBB:选择第一个AAA下的BBB元素
//AAA/BBB[1]:选择所有AAA的第一个BBB元素
//AAA/BBB[last()]:选择所有AAA的最后一个BBB元素
第五种形式:
//@id:选择所有的id属性
//BBB[@id]:选择具有id属性的BBB元素
第六种形式:
//BBB[@id=‘b1’] :选择含有属性id并且其值为b1的BBB元素

3.路径的问题

如果我们的XPath表达式以 “/” 开头,那么表示相对于整个文档进行搜索;
如果我们的XPath表达式以结点(标签)名开头,那么表示相对于调用搜索方法的结点进行搜索;
举个例子:
// 首先我们拿到了student的父标签 students
Node students = doc.selectSingleNode("/classroom/persons/students");
// 以下两种方式搜索的结果是相同的
List<?> list1 = students.selectNodes("/classroom/persons/students/student"); // 以 “/” 开头
List<?> list2 = students.selectNodes(“student”); // 以标签名开头

4.测试案例
<?xml version="1.0" encoding="utf-8"?>
<classroom grade="primary5">
	<persons>
		<teacher id="1">
			<property name="name" value="laosi"/>
			<property name="age" value="24"/>
		</teacher>
		
		<students>
			<student id="1">
				<property name="name" value="lisi"/>
				<property name="age" value="12"/>
			</student>
			<student id="2">
				<property name="name" value="zhangsan"/>
				<property name="age" value="12"/>
			</student>
			<student id="3">
				<property name="name" value="wangwu"/>
				<property name="age" value="12"/>
			</student>
		</students>
	</persons>
</classroom>

使用XPath读取XML文件

@Test
public void xpath1() throws Exception{
    //1.创建解析器对象
    SAXReader reader = new SAXReader();
    //2.读取xml文件
    Document document = reader.read(new File("src/student.xml"));
    Node students = document.selectSingleNode("/classroom/persons/students");
    List<Element> list1 = students.selectNodes("student"); // 以标签名开头
    for (Element element : list1) {
        System.out.println(element.getName()+"=="+element.attributeValue("id"));
        List<Element> list2 = element.elements();//获取当前节点的子节点
        for (Element element2 : list2) {
            System.out.println("\t"+element2.getName());
            System.out.println("\t\t"+element2.attributeValue("name") + "-->" + 
                                      element2.attributeValue("value"));
        }
    }
}

可以根据节点路径直接获取节点,不用全部遍历所有节点;效率会更高。

处理上面把一组员工信息写入XML的案例:

@Test
public void xpath2() throws Exception {
    try {
        // 读取xml文件转换为Document
        SAXReader reader = new SAXReader();
        Document doc = reader.read(new File("src/emp.xml"));
        String path = "/list/emp[gender='女']/salary[.>4000]";
        List<Element> list = doc.selectNodes(path);
        for (Object o : list) {
            Element e = (Element) o;
            System.out.println(e.getText());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

第2种主流技术是W3C规范的DOM解析XML文件。

DOM解析XML文件

微信支付接口案例

请求参数和响应结果都是XML格式的字符串,发送请求的时候我们需要把对象的数据转换成XML格式的字符串,解析响应的时候我们需要把返回的XML格式的字符串转换成对象。微信支付案例如下:

把请求对象转换成XML字符串

请求数据格式

字段名变量名必填类型说明
商户编号mchuidint商户授权接口获取到的商家ID
门店编号mchmidint商户授权接口获取到的门店ID
总金额totalString支付总金额 单位:元 最小金额0.01元 不允许包含任何字、 符号
付款码auth_codeString扫码支付授权码, 设备读取用户展示的条码 或者二维码信息
终端号terminal_numberStringpos端生成

第一步: 把需要传输的参数封装成一个对象:

package com.ujiuye.xml;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.TreeMap;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import cn.hutool.core.util.XmlUtil;
public class RequestData {
    /**
     * 商户授权接口获取到的商家ID
     */
    private Integer mchuid;

    /**
     * 商户授权接口获取到的门店ID
     */
    private Integer mchmid;
    /**
     * 支付总金额 单位:元 最小金额0.01元 不允许包含任何字、 符号
     */
    private String total;

    /**
     * 扫码支付授权码, 设备读取用户展示的条码 或者二维码信息
     */
    private String auth_code;

    /**
     * pos端生成
     */
    private String terminal_number;


    /**
     * 把请求参数解析成xml文件
     * <response>
     * 	<total>
     * 		180
     *  </total
     * </response>
     */
    public static String getXml(RequestData requestData) {
        Document document = XmlUtil.createXml();//创建XML文件
        document.setXmlStandalone(true);//单独文件,无需验证
        Element root = document.createElement("response");//创建根节点
        try {
            Class<? extends RequestData> requestDataClass = requestData.getClass();
            Field[] declaredFields = requestDataClass.getDeclaredFields();
            //签名需要对数据进行排序: 使用SortedMap
            Map<String, String> signData = new TreeMap<>();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                signData.put(field.getName().toString(), field.get(requestData).toString());
            }
            //遍历map生成XML文档
            for (Map.Entry<String, String> entry : signData.entrySet()) {
                Element element = document.createElement(entry.getKey());
                element.setTextContent(entry.getValue());
                root.appendChild(element);//创建的新节点添加到根节点
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        document.appendChild(root);//把根节点添加的document
        System.out.println("构建的XML文件内容:\n" + XmlUtil.toStr(document));
        return XmlUtil.toStr(document);
    }
    //生成getter、setter方法和无参、有参构造方法
}

lombok插件的安装 可以帮助我们生成getter、setter、无参构造、有参构造、toString等方法,简化编码。

单步测试, 注意从test1方法到test2方法再到test3方法。

package com.ujiuye.xml;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.TreeMap;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import cn.hutool.core.util.XmlUtil;

public class RequestDataTest {
	//思考题: 所有的属性安装字典顺序排序生成xml文件,ASCII
	@Test
	public void test3() throws Exception {
		//创建XML文档
		Document document = XmlUtil.createXml();
		//创建根节点
		Element root = document.createElement("response");
		//遍历对象的所有属性
		RequestData data = new RequestData(1001,123456,"180","2342894234835234","6666");
		//反射Class对象,Class是反射的入口,照妖镜
		Class<?> clazz = data.getClass();
		//获取获取所有的属性
		Field [] fileds = clazz.getDeclaredFields();
		//遍历所有的属性
		//创建一个有序的map
		Map<String,String> map = new TreeMap<>();
		for (Field field : fileds) {
			//Accessible adj. 易接近的;可进入的;可理解的
			field.setAccessible(true);//破门而入,强制访问  set设置,get获取
			System.out.println(field.getName() + "-->" + field.get(data));
			map.put(field.getName(), field.get(data).toString());
		}
		//把map中有序的数据写到xml文件
		for(Map.Entry<String, String> entry : map.entrySet() ) {
			//每一个属性封装成一个节点
			Element element = document.createElement( entry.getKey() );
			element.setTextContent(entry.getValue());
			//把当前节点加入到root
			root.appendChild(element);
		}
		System.out.println(map);
		//把root添加到xml文件
		document.appendChild(root);
		//输出文件
		System.out.println(XmlUtil.toStr(document));
	}
	@Test
	public void test2() throws Exception {
		//创建XML文档
		Document document = XmlUtil.createXml();
		//创建根节点
		Element root = document.createElement("response");
		//遍历对象的所有属性
		RequestData data = new RequestData(1001,123456,"180","2342894234835234","6666");
		//反射Class对象,Class是反射的入口,照妖镜
		Class<?> clazz = data.getClass();
		//获取获取所有的属性
		Field [] fileds = clazz.getDeclaredFields();
		//遍历所有的属性
		for (Field field : fileds) {
			//Accessible adj. 易接近的;可进入的;可理解的
			field.setAccessible(true);//破门而入,强制访问  set设置,get获取
			System.out.println(field.getName() + "-->" + field.get(data));
			//每一个属性封装成一个节点
			Element element = document.createElement( field.getName() );
			element.setTextContent(field.get(data).toString());
			//把当前节点加入到root
			root.appendChild(element);
		}
		//把root添加到xml文件
		document.appendChild(root);
		//输出文件
		System.out.println(XmlUtil.toStr(document));
	}
	@Test
	public void test1() throws Exception {
		//遍历对象的所有属性
		RequestData data = new RequestData(1001,123456,"180","2342894234835234","6666");
		//反射Class对象,Class是反射的入口,照妖镜
		Class<?> clazz = data.getClass();
		//获取获取所有的属性
		Field [] fileds = clazz.getDeclaredFields();
		//遍历所有的属性
		for (Field field : fileds) {
			//Accessible adj. 易接近的;可进入的;可理解的
			field.setAccessible(true);//破门而入,强制访问  set设置,get获取
			System.out.println(field.getName() + "-->" + field.get(data));
		}
	}
}

微信支付签名:
在这里插入图片描述

Hutool工具包应用

糊涂的意思,重点学习日期工具类、XML工具类、HTTP请求的工具类。

HuTool官网

官方文档

Maven官网

DTD&Schema

XML文件是不同系统之间传输数据的格式,有个问题: XML文件使用哪些标签、标签有哪些属性、标签有哪些子标签这些需要事先定义好的;否则不同系统无法传输并解析XML文件。为了解决这个问题, 产生了两种XML约束的规范:

  • DTD document type defination 文档类型定义
  • Schema XML模式,也是定义XML的规范

DTD案例

mybatis的配置文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<typeAliases>
		<typeAlias type="com.news.entity.Dept" alias="Dept"/>
	</typeAliases>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql:///db1" />
				<property name="username" value="root"/>
				<property name="password" value="admin"/>
				
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/news/entity/deptMapper.xml" />
	</mappers>
</configuration>

该XML文件的DTD约束是: http://mybatis.org/dtd/mybatis-3-config.dtd

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 定义了该XML文件可以出现的节点名称 -->
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>

<!ELEMENT databaseIdProvider (property*)>
<!ATTLIST databaseIdProvider
type CDATA #REQUIRED
>

<!ELEMENT properties (property*)>
<!-- attribute list  属性列表可以出现的属性: resource和url -->
<!ATTLIST properties
resource CDATA #IMPLIED
url CDATA #IMPLIED
>

Schema约束

Spring的配置文件就是使用Schema约束,创建web项目的web.xml文件也是使用Schema约束,Schema逐步替换DTD

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>chapter12</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

web.xml文件的约束就是: http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd,这是一个schema约束文件。schema相比较DTD有更好语义支持,可以定义数据类型;一些开源框架都是使用schema定义XML文件的约束。

HTTP协议

简介:

http是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使得开发和部署是那么的直截了当。

工作原理

HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:

(1)客户与服务器建立连接;

(2)客户向服务器提出请求;

(3)服务器接受请求,并根据请求返回相应的文件作为应答;

(4)客户与服务器关闭连接。

客户与服务器之间的HTTP连接是一种一次性连接,它限制每次连接只处理一个请求,当服务器返回本次请求的应答后便立即关闭连接,下次请求再重新建立连接。这种一次性连接主要考虑到WWW服务器面向的是Internet中成干上万个用户,且只能提供有限个连接,故服务器不会让一个连接处于等待状态,及时地释放连接可以大大提高服务器的执行效率。 [8]

HTTP是一种无状态协议,即服务器不保留与客户交易时的任何状态。这就大大减轻了服务器记忆负担,从而保持较快的响应速度。HTTP是一种面向对象的协议。允许传送任意类型的数据对象。它通过数据类型和长度来标识所传送的数据内容和大小,并允许对数据进行压缩传送。当用户在一个HTML文档中定义了一个超文本链后,浏览器将通过TCP/IP协议与指定的服务器建立连接。 [8]

从技术上讲是客户在一个特定的TCP端口(端口号一般为80)上打开一个套接字。如果服务器一直在这个周知的端口上倾听连接,则该连接便会建立起来。然后客户通过该连接发送一个包含请求方法的请求块。

HTTP规范定义了9种请求方法,每种请求方法规定了客户和服务器之间不同的信息交换方式,常用的请求方法是GET和POST。服务器将根据客户请求完成相应操作,并以应答块形式返回给客户,最后关闭连接。
在这里插入图片描述

常规

请求URL: 请求的地址

请求方法: get post

状态代码: 302

远程地址: 服务器地址

引用站点策略: 没有引用,直接通过浏览器地址访问的

响应头

Connection: 连接

Content-Length: 内容长度

Date: 时间

Keep-Alive: 20毫秒

Location: 地址

请求头:

表单数据:

反射技术

反射技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值