7行程式碼搞定WEB服務
- 2019 年 10 月 4 日
- 筆記
【這是一猿小講的第 50 篇原創分享】
作為一個 Java 程式猿,寫程式碼久了,各種技術也就都嘗試了一個遍。先從 SSH1(Spring、Struts1、Hibernate)摸爬滾打轉變到 SSH2(Spring、Struts2、Hibernate),誰成想 Struts 漏洞頻出,於是 S2 的江湖地位很快被 SpringMVC 佔領,隨著時間的推移,未成想 MyBatis 也逐漸取代了 H 的江湖地位,於是 SSH2 就變成了現在依舊有項目在用SSM(Spring、SpringMVC、MyBatis),而今眼目下幾乎被 Spring 全家桶包圓了。
我們都知道無論是 SSH 也好、還是 SSM 也罷,搭建時都會依賴一堆的 JAR 包和一坨坨的程式碼,而今天一次無心的 flask 嘗試,感覺提供一個 WEB 服務真的好簡單。
啥也不說,先上程式碼,去除空行,真的只有 7 行程式碼!!!
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'flask 真好!' if __name__ == '__main__': app.run()跑起來,看一看是不是那麼回事兒。

瀏覽器訪問一下,再探探虛實,果不其然還真能夠訪問。

1. Flask 是啥?
簡單了解,吹吹牛逼。Flask 其實是一個使用 Python 編寫的可訂製的輕量級 Web 應用微框架,特點就是靈活、輕便、容易上手。

2. 小插曲湊起來,如何發送 JSON 請求?
工作中用過很多模擬發包的工具,用過自己開發的 Jar 包模擬發包,用過瀏覽器插件模擬發包,但是用的最舒服的莫過於 postman 啦,不妨花半分鐘時間一起體驗體驗。
首先根據下載鏈接完成安裝。
https://www.getpostman.com/downloads/
然後打開頁面配置請求頭,在Headers中添加key為Content-Type,value 為 application/json的鍵值對。

然後在請求體 Body 中擼入要發送的 JSON 報文,點擊 Send 就 OK!

Postman 半分鐘就掌握了,點擊 send,我們接下來還是回歸主題,繼續摸索 Flask。
3. 如何獲取 JSON 請求?
Flask提供了好幾種方式獲取請求參數,先嘗試用 request.get_json() 獲取試試。
from flask import Flask from flask import request app = Flask(__name__) @app.route('/', methods=['post']) def hello_world(): # 方式一 接受JSON請求參數 predict_data = request.get_json() app.logger.debug('request data %s', predict_data) contract_id = predict_data['contract_id'] app.logger.debug("contract_id %s", contract_id) return 'flask 真好!' if __name__ == '__main__': app.debug = True app.run()用 Postman 發送 JSON 報文,點擊 send,我們會看到控制台日誌輸出發現傳入的 JSON 數據正常獲取,真簡單!
DEBUG in predict_server: request data {'contract_id': 'c90121010'}
DEBUG in predict_server: contract_id c90121010
趁熱乎勁,再嘗試一下 request.get_data(),實踐中發現此種就沒有想像的那麼任性了,出了一堆的幺蛾子,後面會列出具體的問題。
from flask import Flask from flask import request import json app = Flask(__name__) @app.route('/', methods=['post']) def hello_world(): # 方式二 接受JSON請求參數 predict_data = request.get_data() app.logger.debug('request data %s', predict_data) predict_data = json.loads(predict_data) contract_id = predict_data['contract_id'] app.logger.debug("contract_id %s", contract_id) return 'flask 真好!' if __name__ == '__main__': app.debug = True app.run()程式碼修改完,flask 會進行實時檢測文件是否修改,然後會進行 reloading,真棒!我們直接用 postman 繼續發送請求即可。
DEBUG in predict_server: request data b'{nt"contract_id":"c90121010"n}'
DEBUG in predict_server: contract_id c90121010
依據日誌輸出,發現JSON請求報文獲取正常。
4. 牛逼的業務咋實現?
開始進行非常牛逼的業務處理,此處用一句輸出代表了所有
print('進行了非常牛逼的業務處理')
5. 響應的內容如何返回 JSON?
Flask 做的真周到,又幫我提供了 jsonify 函數供我們處理返回的序列化 JSON 數據。
# 封裝返回參數 JSON 格式
ret_data = {'ret_code': '0000', 'ret_msg': '成功'}
ret_data = jsonify(ret_data)
6. 整體回顧跑跑看
完整的示例程式碼。
from flask import Flask, jsonify from flask import request app = Flask(__name__) @app.route('/', methods=['post']) def hello_world(): # 接受 JSON 請求參數 predict_data = request.get_json() print('接收請求參數: {0}'.format(predict_data)) # 業務處理 print('進行了非常牛逼的業務處理') # 封裝返回參數 JSON 格式 ret_data = {'ret_code': '0000', 'ret_msg': '成功'} ret_data = jsonify(ret_data) print('響應資訊: {0}'.format(ret_data)) return ret_data if __name__ == '__main__': app.run()藉助 postman 再一次發送請求。

看看服務的日誌,參數接收正常、業務處理完畢、響應資訊封裝,一切都是那麼的自然。

出現了哪些幺蛾子?
- OSError: [Errno 48] Address already in use 把 5000 埠的進程直接殺掉就行,mac 下用 lsof -i:5000 看哪個進程在佔用 5000 埠;然後用 kill -9 PID 把對應 PID 的進程幹掉。
- TypeError: byte indices must be integers or slices, not str 當predict_data=request.get_data()獲取數據時,然後直接取 predict_data['contract_id'],因為未轉變成 JSON,所以會報此種錯誤。
- AttributeError: 'bytes' object has no attribute 'read' (json.load) 當 json.loads(predict_data) 中的loads漏掉s誤寫成 json.load(predict_data) 時,會提示此種錯誤。
7. 寫在最後
好了,技術的更新迭代就是快,幾分鐘的簡單分享,主要讓你接觸並認識一下 flask,並播了一個 postman 的插曲,希望你能夠喜歡吧。
最後阿里新六脈神劍中的三脈送給大家:今天最好的表現是明天最低的要求;此時此刻非我莫屬;認真生活快樂工作!