前言
在做Web應用程序開發時,在不同的系統之間,經常需要通過Http協議進行通訊。
API要給前端提供接口,接口開發完畢之後,除了進行各個功能單元的單元測試之外,我們還要模擬前端的調用,進行測試。
這種類型的測試,有多種實現辦法,比如:
測試方法 | 優點 | 缺點 |
1、寫個測試工程,模擬客戶端調用 | 和工程集成在一起,不容易丟失 | 開發工作量 |
2、使用瀏覽器插件(比如Postman、DHC),模擬客戶端調用 | 可以保存訪問URL,操作簡單 | 如果後端負載均衡,想測試某臺機器,比如,發版驗證,則不適用 |
3、使用Linux命令(curl),模擬客戶端調用 | 滿足所有場景 | 需要熟悉命令 |
以上各種測試辦法各有優缺點,需要根據具體的應用場景進行選擇。
本文單獨介紹強大的curl,熟練掌握這個命令,不但可以滿足各種Http測試場景,而且隨着使用的逐步熟練,對於Http協議的掌握,也很有幫助。
curl
參考網址:
curl網站開發指南:http://www.ruanyifeng.com/blog/2011/09/curl.html
Http狀態嗎詳解:http://tool.oschina.net/commons?type=5
cur是強大的,支持多種協議,以http爲例,可以模擬多種方式的提交(GET/POST Form/Multipart/Json)。
下面結合服務器端的配置,以及SpringMVC,熟練一些 curl 命令的使用,及返回錯誤Http狀態碼時的場景。
curl 錯誤狀態
錯誤描述 | 錯誤原因 |
curl: (7) Couldn't connect to server | 如果由於本地網絡的原因,不能連接外網,則報此錯誤 |
curl: (7) Failed to connect to 127.0.0.1 port 8411: Connection refused | 如果應用還沒有啓動(判斷依據:8411端口沒有開啓監聽),則報此錯誤 |
Error 503 Service Unavailable | 如果應用已經啓動(判斷依據:8411端口已經開啓監聽),但是應用不正常,則可能獲取到錯誤信息 |
curl http 狀態碼
400
錯誤 | Error 400 Required String parameter 'test' is not present |
SpringMVC 代碼 |
@ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestParam(value="test", required=false) String test) |
錯誤的 curl 代碼 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --data test=中國 http://127.0.0.1:8411/test/test.do |
錯誤原因 | 請求時定義了“Entity Head Field”,Content-Type json,導致--data失效 |
正確的 curl 代碼 | curl -X POST --form test=中國 http://127.0.0.1:8411/test/test.do curl -X POST --data test=中國 http://127.0.0.1:8411/test/test.do |
401
Web服務器開啓了認證,而客戶端沒有傳入認證信息,或者認證信息錯誤。最基本的是Basic 認證,截個圖說明一下吧,如下:
雖然在各種Web服務器(Nginx,IIS等),很容易的配置BA認證,但由於用戶名和密碼都是作爲明文傳遞的,所以並不安全。
Amazon的一種認證方法,相比較Basic認證,一樣使用簡單,但是安全的多,有一些公司在使用,相關文檔如下:
http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
http://my.oschina.net/darcyzhu/blog/2724
405
錯誤 | Error 405 Request method 'GET' not supported |
SpringMVC 代碼 |
@ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestParam(value="test", required=false) String test) |
錯誤的 curl 代碼 | curl -X GET --data test=中國 http://127.0.0.1:8411/test/test.do |
錯誤原因 | Http Method不匹配,服務端支持POST,客戶端用GET發起請求 |
正確的 curl 代碼 | curl -X POST --form test=中國 http://127.0.0.1:8411/test/test.do curl -X POST --data test=中國 http://127.0.0.1:8411/test/test.do |
406
錯誤 | Error 406 Not Acceptable |
SpringMVC 代碼 |
@ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestBody TestUserInfo userInfo) |
錯誤的 curl 代碼 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --header "Accept:text/html,application/xhtml+xml,application/xml;q=0.9" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
錯誤原因 | 請求Accept和相應的媒體類型不一致 |
正確的 curl 代碼 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --header "Accept:application/json" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
413
415
錯誤 | Error 415 Unsupported Media Type |
SpringMVC 代碼 |
@ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestBody TestUserInfo userInfo) |
錯誤的 curl 代碼 | curl -X POST --header "Accept:text/html,application/xhtml+xml,application/xml;q=0.9" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
錯誤原因 | 沒有定義媒體類型,默認用text/plain,服務器端不支持 |
正確的 curl 代碼 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --header "Accept:application/json" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
http
通過 curl 的使用,也加深了我們對 http 這種應用層協議的理解。
應用層協議,應用層面的規範,定義一套請求的規範,定義一套響應的規範,由於這是國際標準化組織的定義,以及工業上的廣泛應用,造就了其廣泛知名度,到達協議的標準。
我們日常工作中,也會定義一些規範;以前工作中也有這種場景,在Soap出來之前,見過牛人用Delphi寫的Http通訊程序程序,也是基於類似於xml標籤的方式,定義了一套請求和響應的規範,自己進行解析,當Soap出來後,發現很像;這些規範上升不到協議的程度,也是以上的原因;
我們把協議從高大上的位置,拽下來,和我們的日常規範一樣的高度,相當於,把抽象的問題形象化,把微觀的問題從宏觀上來理解,對於協議的入門理解,很有好處。