【计算机网络笔记七】应用层(四)HTTP 通过Content-Type提交数据的方式

1. Content-Type: application/x-www-form-urlencoded 表示纯文本表单提交方式

格式如下:

POST /users HTTP/1.1 
Host: api.github.com
Content-Type: application/x-www-form-urlencoded 
Content-Length: 27name=zhangsan&gender=male 

对应的 Retrofit 代码:

@FormUrlEncoded
@POST("/users")
Call<User> addUser(@Field("name") String name, @Field("gender") String gender);

对于 GET 请求也有可能使用这种类型。

2. Content-Type: multipart/form-data;boundary=[分隔符] 包含文件的多文本表单提交方式

格式如下:

POST /home/upload.html HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.24.56
Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2
Content-Length: 3693
Connection: Keep-Alive

-------------------------------7db372eb000e2
Content-Disposition: form-data; name=“username”

admin
-------------------------------7db372eb000e2
Content-Disposition: form-data; name=“file”; filename=“kn.jpg”
Content-Type: image/jpeg
(此处省略jpeg文件二进制数据…)

-------------------------------7db372eb000e2–

注意这一行: Content-Type: multipart/form-data; boundary=---------------------------7db372eb000e2,根据 RFC1867,在这种方式下,Content-Type:multipart/form-data 字段是必须的。它包括一个名为 boundary 的标志,它可以是随便输入的字符串,对后面的具体内容也是必须的它用来分辨一段内容的开始

Content-Length: 3693 ,这里的 3693 是要上传文件的总长度。

绿色字体部分就是需要上传的数据,可以是文本,也可以是图片等。数据内容前面需要有 Content-Disposition, Content-Type 以及 Content-Transfer-Encoding 等说明字段。

最后的紫色部分就是协议的结尾了。

---------------------------7db372eb000e2 是分隔符,分隔多个文件、表单项。其中 b372eb000e2 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。

Form 每个部分用分隔符分割,分隔符之前必须加上 “--” 这两个字符(即--{boundary})才能被 http 协议认为是 Form 的分隔符,表示结束的话,在正确的分隔符后面添加"--"表示结束(即--{boundary}--)。

前面的 ---------------------------7d 是 IE 特有的标志,Mozila 为---------------------------71

每个分隔的数据的都可以用 Content-Type 来表示下面数据的类型,可以参考 rfc1341 例如 :Contect-Type:image/jpeg 表示下面的数据是jpeg文件数据。

对应的 Retrofit 代码:

@Multipart
@POST("/users")
Call<User> addUser(@Part("name") RequestBody name, @Part("avatar") RequestBody avatar);
...
RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"), nameStr);
RequestBody avatarPart = RequestBody.create(MediaType.parse("image/jpeg"), avatarFile);
api.addUser(namePart, avatarPart); 

3. Content-Type: application/json 表示提交 json 格式的数据

格式如下:

POST /users HTTP/1.1
Host: app.test.com
Content-Type: application/json; charset=utf-8 
Content-Length: 38{"name":"zhangsan","gender":"male"} 

对应的 Retrofit 代码:

@POST("/users")
Call<User> addUser(@Body("user") User user); 
...
// 需要使用 JSON 相关的 Converter
api.addUser(user); 

响应中返回 JSON:

HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8 
Content-length: 234[{"login":"mojombo","id":1,"node_id":"MDQ6VXN1 cjE=",
"avatar_url":"https://avatars0.githubuse rcontent.com/u/1?v=4",
"gravat":....}]

4. Content-Type: image/jpeg 表示提交二进制文件内容,上传单个文件

格式如下:

POST /user/1/avatar HTTP/1.1 
Host: app.test.com
Content-Type: image/jpeg 
Content-Length: 1575 JFIFHH9......

对应的 Retrofit 代码:

@POST("users/{id}/avatar")
Call<User> updateAvatar(@Path("id") String id, @Body RequestBody avatar);
...
RequestBody avatarBody = RequestBody.create(MediaType.parse("image/jpeg"), avatarFile);
api.updateAvatar(id, avatarBody)

响应中返回二进制内容:

HTTP/1.1 200 OK
Content-type: image/jpeg 
Content-length: 1575 JFIFHH9......

Content-Type 类型 / MIME 类型的获取

常见的 body 数据类型主要有以下四大类:

  • text: 文本格式的可读数据,如 text/html 超文本,text/plain纯文本,text/css样式表等

  • image: 图像文件,如 image/gifimage/jpegimage/png

  • audio/video: 音频和视频数据,如audio/mpegvideo/mp4

  • application:格式不固定,可以是文本或二进制,必须由上层应用来解释,常见的有 application/jsonapplication/javascriptapplication/pdf

  • 如果不知道数据是什么类型就用 application/octet-stream 即不透明的二进制数据

完整的类型对照表可以参考 IANA 维护的 MIME 类型列表:https://www.iana.org/assignments/media-types/media-types.xhtml

实际上我们不需要记住这些,在所使用的开发语言中有很多系统自带方法或者三方库可以直接根据文件输出其 MIME 类型。

在 Android 中,有两种自带的方法可以获取一个文件的 MIME 类型

  1. 通过 MimeTypeMap 来获取
  2. 通过 ContentResolver 来获取

下面是使用MimeTypeMap来根据一个File对象获取其 MIME 类型的示例代码:

import android.webkit.MimeTypeMap;public String getMimeType(File file) {String mimeType = null;String extension = MimeTypeMap.getFileExtensionFromUrl(file.getAbsolutePath());if (extension != null) {mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());}return mimeType;
}

这个方法首先使用MimeTypeMap.getFileExtensionFromUrl()来获取文件的扩展名,然后使用MimeTypeMap.getSingleton().getMimeTypeFromExtension()来获取对应的 MIME 类型。最后,它返回找到的 MIME 类型字符串。

请注意,这种方法依赖于文件扩展名来确定 MIME 类型,因此文件的扩展名必须正确设置。如果文件没有扩展名或扩展名不正确,那么这个方法可能无法正确识别 MIME 类型。

但是有时我们开发中得到的是一个从系统媒体数据库中查询到的 Content Uri 对象 (例如content://media/external/images/media/94),它是不带文件扩展名的,这时该如何获取其 MIME 类型呢?

此时可以考虑使用 ContentResolver,下面是使用 ContentResolver 获取 Content Uri 的参考代码:

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;public String getMimeTypeFromContentUri(Context context, Uri contentUri) {ContentResolver contentResolver = context.getContentResolver();String mimeType = contentResolver.getType(contentUri);return mimeType;
}

还有一种情况是,我们有一个 File 类型的 Uri (即以 file 开头的,如 file://xxx/xx)可以通过如下参考代码获取:

String fileExtension = MimeTypeMap.getFileExtensionFromUrl(fileUri.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase());

以下参考代码可同时适用于 Content Uri 和 File Uri 的情况:

public String getMimeType(Context context, Uri uri) {String mimeType = null;if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {ContentResolver cr = context.getContentResolver();mimeType = cr.getType(uri);} else {String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri.toString());mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase());}return mimeType;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/93639.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何安装并启动jupyter notebook

jupyter是什么 Jupyter Notebook 可以使用多种语言&#xff08;Python、R、Julia 等&#xff09;开发交互式笔记本&#xff0c;因此&#xff0c;它会依赖于不同的包和库。但是&#xff0c;对于 Jupyter Notebook 的 Python 版本&#xff0c;以下是一些主要的依赖项&#xff1a…

样品运输与贮存

声明 本文是学习GB-T 42959-2023 饲料微生物检验 采样. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了以微生物检验为目的的采样原则、采样人员、设备和材料、采样方案、采样步骤和采样 报告。 本文件适用于以微生物检验为目的…

flutter开发实战-webview插件flutter_inappwebview使用

flutter开发实战-webview插件flutter_inappwebview使用 在开发过程中&#xff0c;经常遇到需要使用WebView&#xff0c;Webview需要调用原生的插件来实现。常见的flutter的webview插件是webview_flutter&#xff0c;flutter_inappwebview。之前整理了一下webview_flutter&…

手机投屏到笔记本电脑小方法

1、我们可以开启Windows自带的投影功能&#xff0c;将我们的手机和电脑连接同一个无线网络。 2、在电脑开始菜单栏里找到设置选项并打开。 3、我们进入之后找到系统选项&#xff0c;点击进去之后找到点击投影到这台电脑&#xff0c;接下来我们将默认的始终关闭的下拉选项更改为…

国庆作业6

TCP服务器 #include "head.h" #define PORT 2580 //端口号 #define IP "192.168.31.219" //本机IP int main(int argc, const char *argv[]) {sqlite3* dbNULL;if(sqlite3_open("./my.db",&db)!SQLITE_OK){fprintf(stde…

257. 二叉树的所有路径

257. 二叉树的所有路径 原题 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode…

OpenGl材质

在现实世界里,每个物体会对光产生不同的反应。比如,钢制物体看起来通常会比陶土花瓶更闪闪发光,一个木头箱子也不会与一个钢制箱子反射同样程度的光。有些物体反射光的时候不会有太多的散射(Scatter),因而产生较小的高光点,而有些物体则会散射很多,产生一个有着更大半径的…

python 使用 scapy 扫描内网IP或端口

地址信息在IP层, 可以利用 ICMP 或 ARP 协议数据包探测IP信息. ICMP协议可以利用ping工具发送数据包, 但是防火墙有可能禁止ICMP, 无法有效探测, 可以考虑使用ARP探测. 利用ICMP协议探测内网IP def ping_ip(ip_fex):# 扫描范围: 128~254for i in range(128, 255):ip f{ip_fe…

匿名上位机V7波形显示教程-简单能用

匿名上位机V7波形显示教程-简单能用 匿名上位机V7下位机数据格式根据匿名上位机V7的手册说明文档&#xff0c;编写对应的指令在主函数中初始化ANDmessage驱动连接匿名上位机V7 匿名上位机V7下位机数据格式 DATA区域内容&#xff1a; 举例说明DATA区域格式&#xff0c;例如上文&…

910数据结构(2020年真题)

算法设计题 问题1 现有两个单链表A和B,其中的元素递增有序,在不破坏原链表的情况下,请设计一个算法,求这两个链表的交集,并将结果存放在链表C中。 (1)描述算法的基本设计思想; (2)根据设计思想,给出C语言描述算法,关键之处请给出简要注释。 (1)基本思想:A、B两个…

【数组及指针经典笔试题解析】

1.数组和指针笔试题 题目1 int main(){int a[5] { 1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5};int * ptr (int * )(&a 1);printf("%d&#xff0c;%d"&#xff0c;*(a 1)&#xff0c;*(ptr - 1));return 0;}图文解析&#xff1a; int * ptr …

selenium京东商城爬取

该项目主要参考与:http://c.biancheng.net/python_spider/selenium-case.html 你看完上述项目内容之后&#xff0c;会发现京东登录是一个比较坑的点&#xff0c;selenium控制浏览器没有登录京东,导致我们自动爬取网页被重定向到京东登录注册页面。 因此&#xff0c;我们要单独…

VC++父进程交互式操作子进程标准输入输出

父进程接管子进程的标准输入输出和错误,实现对子进程的交互操作。比如子进程是一个类似mysql这种可以交互的命令,执行操作后输出结果,父进程根据结果分析决定执行下一步的命令,从而替代人工的输入。 通过父进程创建子进程,使用管道重定向子进程的输入输出错误可以实现 在 …

数据结构与算法——19.红黑树

这篇文章我们来讲一下红黑树。 目录 1.概述 1.1红黑树的性质 2.红黑树的实现 3.总结 1.概述 首先&#xff0c;我们来大致了解一下什么是红黑树 红黑树是一种自平衡的二叉查找树&#xff0c;是一种高效的查找树。红黑树具有良好的效率&#xff0c;它可在 O(logN) 时间内完…

P1541 [NOIP2010 提高组] 乌龟棋

[NOIP2010 提高组] 乌龟棋 - 洛谷 #include<bits/stdc.h> using namespace std; const int N41; int f[N][N][N][N],num[351],g[5],n,m,x; int main() {scanf("%d %d",&n,&m);for(int i1;i<n;i)scanf("%d",&num[i]);f[0][0][0][0]nu…

解决u盘在我的电脑中重复显示两个

删除注册表&#xff1a; [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\DelegateFolders\{F5FB2C77-0E2F-4A16-A381-3E560C68BC83}]

Maven下载源码出现:Cannot download sources Sources not found for org.springframwork...

Maven下载源码出现&#xff1a;Cannot download sources Sources not found for org.springframwork… 最近重装了IDEA再次查看源码时发现总是报错&#xff0c;网上找了很多&#xff0c;发现解决方法都是在项目终端执行如下命令&#xff1a; mvn dependency:resolve -Dclassi…

基于MFC和OpenCV实现人脸识别

基于MFC和OpenCV实现人脸识别 文章目录 基于MFC和OpenCV实现人脸识别1. 项目说明1. 创建项目2. 启动窗口3. 登录窗口-添加窗口、从启动窗口跳转4. 启动窗口-美化按钮5. 登录窗口-美化按钮、雪花视频6. 注册窗口-美化按钮、雪花视频、从启动窗口跳转7. 注册窗口-开启摄像头8. 注…

PE文件之导入表

1. 导入表 2. 显示导入表信息的例子 ; 作用: 将RVA地址转成FOA即文件偏移 ; 参数: _pFileHdr 指向读到内存中文件的基址指针 ; _dwRVA 目标RVA地址 ; 返回: 目标RVA转成文件偏移的值 RVA2FOA PROC USES esi edi edx, _pFileHdr:PTR BYTE, _dwRVA:DWORDmov esi, _pFil…

栈的应用场景(二)

有效的括号匹配 1.题目2.图分析3.代码实现 1.题目 2.图分析 3.代码实现 class Solution {public boolean isValid(String s) {//创建一个栈,来放左括号.Stack<Character> stack new Stack<>();//遍历字符串,左括号放进栈for(int i 0 ; i < s.length(); i){ch…