之前在做一个图片上传的功能时,由于是和新的同事进行对接,我居然没有开始就用封装好的方法!现在想想如果不是这样,也不能对HTTP的认识更加深刻了。而且还小小的了解了一下Java服务器的后台知识。
最原先我是将参数以及文件内容放在了HTTPBody里。
然后发出的报文其实就跟这个文章里面介绍的一样了:iOS POST 至 Java后台
但是失败了。。。而且返回的错误是服务器的错误码,好像是415吧~ 这样的话,说明同事的那个方法都没有进去。那么,有可能就是参数的问题。
后来让同事分别多写了两个方法,一个是只传参数,一个是只传文件的方法。测试之后发现只传参数的那个方法是可以调通的。
仔细分析两者的报文,再加上对比之前Web端的请求报文。发现问题应该是出现在了HTTP表单中的Content-Type这个字段里。
先附上一个前些日子收藏的关于HTTP协议的一篇帖子:HTTP协议详解
一般我们使用iOS请求网络的原生方法,或者使用AFNetworking时,如果没有特殊写明Content-Type这个字段的值,那么默认的应该就是:application/x-www-form-urlencoded这个值。比如下图
request_header.png
这种情况下的GET请求呢,会把所有参数转换为一个字符串,然后拼接在请求的地址后面,用?分割。如果是POST请求,会将数据封装到HTTPBody里面。
如果在请求里面有文件的话,那么你的Content-Type的值就不能是默认的值了,而应该是:multipart/form-data。比如下图
图片.png
而报文呢,也是有所不同,比如下图:
图片.png
图中上面的红框是普通的参数封装的样子,下面的红框是文件类型的参数封装的样子,下面那些乱码就是文件的Data流了。
那么,果断按照这种格式向服务器发起请求!
结果,出错了。
为什么呢?
和同事沟通过后发现,在这个接口的方法上方,有一个很显眼的关键字。
@RequestBody
以及@RequestMapping(value = "*********",consumes = 'application/json')
比如下图:
java_method.png
后台使用的是SpringMVC 的架构。
这样的设置,意味着接收的数据是json格式的字符串。然后将这个字符串封装到指定的对象里。也就是图中的
NativeReplayPo replay这个对象里。
将其删掉,重新请求,轻轻松松的就成功了。
经过这次风波之后,真是感慨,这个世界上如果有比女人更难懂的,那应该就是HTTP了。
也是自己基础的知识不够完善。写下此文,以示警戒。