PythonでJSONを受けて処理する(ABC版)
抽象クラスを作成して、http://d.hatena.ne.jp/matasaburou/20151003/1443882557を作成。
Python3で動作確認済み。
Python2で動かす場合は下記が必要。
- 「from http.server」ではなく「from BaseHTTPServer」にする
- styleの違いでエラーが出るので、ABCとabstractmethodは使用しない
myResponseHandler.py
# -*- coding: utf-8 -*- from abc import ABCMeta, abstractmethod from http.server import BaseHTTPRequestHandler # # HTTPリクエストハンドラ 抽象クラス # class MyRequestHandler(BaseHTTPRequestHandler, metaclass=ABCMeta): def initialize(self, requestCharset='UTF-8', responseCharset='UTF-8', statusCode=200, responseContentType='text'): """ __init__はHTTPServer側から引数なしで呼び出されるため、初期化処理を別途実施します。 """ # 文字コード self._reqCharset = requestCharset self._respCharset = responseCharset # リザルトコード self._code = statusCode # コンテンツタイプ self._respContentType = responseContentType def _loadRequestBody(self): """ HTTPリクエストからリクエストボディを取得します。 """ content_length = int(self.headers.get('content-length')) return self.rfile.read(content_length).decode(self._reqCharset) def _setResponseHeaders(self): self.send_response(self._code) self.send_header('Content-type', self._respContentType) self.end_headers() @abstractmethod def parseRequest(self, requestBody): """ HTTPリクエストBODYを解析します。 特に解析が必要ない場合、下記のような実装が必要です。 def parseRequest(self, requestBody): pass """ raise NotImplementedError() @abstractmethod def createResponse(self): """ HTTPレスポンスBODYを作成します。 特に解析が必要ない場合、下記のような実装が必要です。 def createResponse(self): return '' """ raise NotImplementedError() def do_POST(self): self.initialize() self.parseRequest(self._loadRequestBody()) responseBody = self.createResponse() if responseBody == None: responseBody = '' elif not isinstance(responseBody, str): responseBody = str(responseBody) self._setResponseHeaders() # レスポンス送信 self.wfile.write(responseBody.encode(self._respCharset))
responseBodyが文字列でなかった場合、文字列に型変換するのは微妙な気がします。
文字列じゃなかったら例外発生させて、createResponse側ではデコレーターで戻り値を強制するのがベター?
jsonResponseHandler.py
# -*- coding: utf-8 -*- import json from src.myRequestHandler import MyRequestHandler # # JSONハンドラ クラス # class JSONRequestHandler(MyRequestHandler): def initialize(self): super().initialize('UTF-8', 'UTF-8', 200, 'text/json') def parseRequest(self, requestBody): # JSONレスポンス作成用の種別を取得します。 jsonData = json.loads(requestBody) self._type = '' if 'type' not in jsonData: self._type = 'notype' else: self._type = jsonData['type'] def createResponse(self): # 種別を元にレスポンスを作成します。 if self._type == 'auth': response = 'do something for auth request.' elif self._type == 'update': response = 'do something for update request.' else: response = 'reponse has undefined type.' return json.dumps({'data': response})
dummyHTTPServer.py
''' Created on 2015/12/29 @author: saburou ''' from src.jsonResponseServer import JSONRequestHandler from http.server import HTTPServer server = HTTPServer(('', 8000), JSONRequestHandler) try: print(u'ダミーHTTPサーバーを開始します。') server.serve_forever() except Exception as e: print(u'ダミーHTTPサーバーを終了します。') type(u'タイプ:' + e) print(u'メッセージ:' + e.message)
HTTPサーバー側のエラー処理は適当。
(例外キャッチの意味はなさそうですが、未確認)
2016/12/25 追記
以下の方がモアベターのようです。
try: print(u'ダミーHTTPサーバーを開始します。') server.serve_forever() except Exception as e: print(u'ダミーHTTPサーバーを終了します。') type(u'タイプ:' + e) print(u'メッセージ:' + e.message) finally: server.server_close()