之前在做一个图片上传的功能时,由于是和新的同事进行对接,我居然没有开始就用封装好的方法!现在想想如果不是这样,也不能对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了。

也是自己基础的知识不够完善。写下此文,以示警戒。