这一次我掉进了Unirest的坑

 路径中的斜杠

  我们常见的网址如 http://www.cnblogs.com/aaa/bbb/1.html 是由多级的结构(目录/文件夹)组成的,这里关注的是其中的aaa和bbb,它们之间用斜杠(/)分隔。从最大自由度来讲,每一级结构的名字是可以随意取的。既然名字可以随意取,而且上下级之间是用/来做分隔,那么如果名字里面有斜杠要怎么办呢?可能有人说Windows不允许啊,在Windows文件夹或者文件的名字里面不能出现斜杠,在web是允许的。由于斜杠在网址中代表上下级结构的分隔符,所以如果某一层的文件夹出现斜杠的话,必须进行转码。具体的这个斜杠就得转成%2F,即是百分号后加2位十六进制表示的ASCII码。所以%2F代表文件夹名字中的斜杠,不代表上下级文件夹的分隔。

Unirest是什么?

  现在软件web化非常流行,而且多数是前后端分离,所以web API通常是给前端调的。但也存在一种可能,就是我们自己写一个软件需要去访问(调用)别人的web API。此时就需要一些组件封装了HTTP协议,然后我们就可以方便地使用。这样的组件很多,但是由于HTTP协议比较复杂,所以实现这样的组件要做到强大+易用,还真的不太容易。在众多HTTP组件之中,Unirest就是难得的封装得非常好用的一套组件。

历险过程

  前段时间我写一个程序需要去访问其他系统的web接口,网址大概长这样:http://www.abc.com/one%2Ftwo/abc,调用接口的结果是下载一个文件。一开始用了其他的组件,但下载的文件内容中的中文是乱码,且文件不完整。由于我对那套组件不熟,所以我就想到换为我比较熟的unirest。于是去 https://mvnrepository.com/ 找了unirest的引用代码,结果发现还不止一个。我也忘了以前是怎么选择的,所以就习惯性地采用那个排名第一的,也就是下载量最大的那个。估计以前也是用那个,以前也没遇到什么问题。三下五除二,说干就干,轻车熟路,一番噼里啪啦,很快弄好了。

  启动机器调试。什么?404(找不到文件资源)?我没看错吧?各种检查,没有发现原因。把代码中的网址复制到浏览器,结果401(未登录)。因为我没有传送认证参数,401就是对的。我多么想代码也能得到401,可他却就是404!但是404是个很不好解决的问题。我知道,资源就在那里,谁知道哪个地方写错了呢。服务器就告诉你“找不到。至于哪里写错了,不知道,你猜”。我进行了各种尝试,也包括把%2F变直接变成斜杠去访问服务器,给的回答是。项目不存在,状态码是200。事情陷入了僵局。

  经同事提醒,使用了抓包工具。原来unirest真的“帮我”把%2F转成斜杠了!好吧,既然你会帮我一次解码,那我就编码两次,让你解一次结果就刚好是对的。编解码我还是懂的。查了一下%的编码是%25,于是我把网址变成这样http://www.abc.com/one%252Ftwo/abc。程序运行,又是404!从抓包工具来看,……,这次他就干脆不解码了,你说气不气人?整个人又陷入了绝望。我那么信赖的unirest,怎么会出现这样的bug?

  接下来怎么办?我还能有其他的选择吗?第一,其他的组件我也不熟,出了问题更是难排查。第2,Unirest基本是业界最好的了,他都搞不定,其他组件会更好吗。

  后来又经过各种排查,排查到了unirest的源头,我又再次去了 https://mvnrepository.com/。看到了这一幕

这个时候我才发现,原来我使用的已经有好几年不更新了,而那个一直有更新的下载量并不是第一。总算又看到了一线希望,马上下载来试这一次,问题解决了!!!他不会自动把网址中的%2F进行转码!

教训啊

  1. 使用unirest要留意你使用的是哪个unirest
  2. 当遇到一些技术问题,走投无路的时候,可以在各个分叉点进行尝试。所以呢,在研发或选型的过程中就要记录这些分叉点。典型的就是有多种选择的时候。

  现在复盘写出来思路很清晰,但是人在事中时,是带着混乱的。往往到了山穷水尽疑无路,而不知道哪里有柳暗花明又一村。

posted @ 2021-03-31 23:47  BillySir  阅读(825)  评论(4编辑  收藏  举报