boundary
最近要做一个组件,即接收客户端的请求,经过一系列的封装,将请求发送给真正的服务端器。可以理解为:客户端使用Http的request的Body存储文件流,将Request发送给服务器。遇到一个问题:传入的是一个文件句柄File,需要转换成byte[]存到request的body中,但是发现boundary找不到,自行在content-Type中加上Boundary字段,发现后台读取不到文件流。
1. 首先自己使用Spring Boot搭了一个简单的server,接收Client发送过来的request,读取body然后输出。启动的是8080端口,path为/hello,代码如下:
2. 客户端的代码:
var file *os.File
file,err = os.Open("src/main/post.txt")
if err != nil {
fmt.println(err)
return
}
defer file.Close()
body := bufio.NewReader(file)
requestWrAPPer.Request.Body = ioutil.NopCloser(body)
(1).第一步使用os.Open打开一个文件,返回的是一个文件句柄os.File类型
(2)然后使用缓冲池的读取方法NewReader构建一个Reader,此处用的是默认的缓冲池大小:4096,当然可以换做这个方法来主动传入一个缓冲池大小NewReaderSize(rd, defaultBufSize)
(3)因为Request的Body是一个io.ReadCloser类型,所以需要调用ioutil.NopCloser方法将Reader类型转换成ReadCloser。
3. 万事俱备,现在执行客户端代码,发现server端报错:
即:缺少boundary。
经查阅资料发现,boundary是HttpRequest为multipart类型的contentType设置的一个分隔符,为了使服务器正确识别文件的起始位置。浏览器会自动生成一个随机数作为Boundary,也可以自己制定一个固定的boundary,但要足够复杂,防止与文件中的内容重复,无法正确识别起始位置。
例如,有Boundary的contentType:"Content-Type", "multipart/form-data; boundary=ABCD"
4. 既然缺少boundary,那么就为其添加一个Boundary。
requestwrapper.Request.Header.Set("Content-Type", "multipart/form-data;boundary="+ multipart.NewWriter(bytes.NewBufferString("")).Boundary())
此处的Boundary()函数是Writer提供的一个会返回一个随机数的Boundary
再次启动,发现server端能够接收到请求,但是,打印request的body,发现内容为空!!!
百思不得其解。。。。
5. 查阅资料,说删除自定义的content-Type字段,尝试了一下,竟然成功。
Request.Header.Del("Content-Type")
原因是:
原来 post 请求上传文件的时候是不需要自己设置 Content-Type,会自动给你添加一个 boundary ,用来分割消息主体中的每个字段,如果这个时候自己设置了 Content-Type, 服务器就不知道怎么分割各个字段,因此就会报错。
如果自己设置了content-Type但是又不设置boundary,自然会出现找不到boundary。
所以!让浏览器自己去设置conten-Type。
文章最后发布于: 2018-08-03 12:07:27
相关阅读
Java后台文件下载的方法: public HttpServletResponse download(String path, HttpServletResponse response) { try {
教你学会看&写 input 文件 原链接:https://www.jianshu.com/p/8c4d45b089b6#fnref7阅读指导本文将会涉及到以下内容: inp 文件的功
@echo off 关闭回显 @echo on打开回显@echo off并不是DOS程序中的,而是DOS批处理中的。当年的DOS,所有操作都用键盘命令来完成,当你
复制粘贴文件或图片之类的东西后回到桌面右击还是会有粘贴,有时会不小心点到很麻烦,那么该如何解决呢?今天给大家推荐一种方法,其实也
String fileName = "中国.doc"; //方法1: response.setHeader("Content-Disposition", "attachment; filename=" + java.