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 再一次發送請求。

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

出現了哪些幺蛾子?

  1. OSError: [Errno 48] Address already in use 把 5000 埠的進程直接殺掉就行,mac 下用 lsof -i:5000 看哪個進程在佔用 5000 埠;然後用 kill -9 PID 把對應 PID 的進程幹掉。
  2. TypeError: byte indices must be integers or slices, not str 當predict_data=request.get_data()獲取數據時,然後直接取 predict_data['contract_id'],因為未轉變成 JSON,所以會報此種錯誤。
  3. AttributeError: 'bytes' object has no attribute 'read' (json.load) 當 json.loads(predict_data) 中的loads漏掉s誤寫成 json.load(predict_data) 時,會提示此種錯誤。

7. 寫在最後

好了,技術的更新迭代就是快,幾分鐘的簡單分享,主要讓你接觸並認識一下 flask,並播了一個 postman 的插曲,希望你能夠喜歡吧。

最後阿里新六脈神劍中的三脈送給大家:今天最好的表現是明天最低的要求;此時此刻非我莫屬;認真生活快樂工作!

Tags: