XML-RPCでメッセージに日本語を通す方法
- サーバ側:SimpleXMLRPCServer.SimpleXMLRPCServer で、公開したい関数 or クラスを登録するだけ
- クライアント側:xmlrpclib.ServerProxy で、呼び出したい関数をコールするだけ
動かす際、Apacheとか何かと連携しないといけないのかと思ったら、全然そんな事なくて、単に書いて python hoge.py という風に呼び出すだけ。
DCOMやCORBAだと、色々 あれこれ しないといけないのに、「何これ?卑怯じゃん。漏れ、すっげー損してたよ!」って感じ。
で、早速遊んでいたら、string(文字列)引数に、日本語を突っ込んだら、エラーが発生する事に気付いた。
... File "/usr/lib/python2.4/xmlrpclib.py", line 1096, in __call__ return self.__send(self.__name, args) File "/usr/lib/python2.4/xmlrpclib.py", line 1383, in __request verbose=self.__verbose File "/usr/lib/python2.4/xmlrpclib.py", line 1137, in request headers xmlrpclib.ProtocolError: <ProtocolError for localhost:8000/RPC2: 500 Internal error>
さっそく ぐぐーる様に お伺いを立てるが、あまり言及する資料が無い。
メーリングリストで、自分と同じ現象で困っている人が居たくらい。
[Python-ml-jp 1497] xmlrpclibで日本語を扱うには?
http://www.python.jp/pipermail/python-ml-jp/2002-June/001494.html
Morf-hine : はてなダイアリーキーワード自動リンクAPI
http://www.zoili.net/203
う〜ん、あんまり日本語を通す要求って無いのかしらん?と思って、サーバとクライアントの両方をUTF-8にしたりして、トライ&エラーで、試してみた。
で、結局の所、
XML-RPCで日本語を通すには、UTF-8に変換して通す必要がある
という事がわかった。
という訳で、実証コードね。
server.py: # -*- encoding: euc_jp -*- import commands import sys import re import SimpleXMLRPCServer def test(msg): print type(msg), len(msg) if type(msg) is unicode: print msg.encode("euc_jp") else: print msg return 0 def main(): srv = SimpleXMLRPCServer.SimpleXMLRPCServer srv.register_introspection_functions( ) srv.register_function(test) print "listen" srv.serve_forever() if __name__ == "__main__": main()
client.py # -*- coding: euc_jp -*- import commands import sys import re import xmlrpclib def main(): print sys.stdout.encoding print sys.getfilesystemencoding() srv = xmlrpclib.ServerProxy("http://localhost:8000") print srv.system.listMethods() while True: c = raw_input(">") if c == "q": break s = unicode(c, "euc_jp", "ignore").encode("utf-8") print type(s), len(s) print srv.test(s) if __name__ == "__main__": main()
実行結果。(Python 2.4.1 for Cygwinでテスト)
クライアント側: $ python client.py US-ASCII US-ASCII ['system.listMethods', 'system.methodHelp', 'system.methodSignature', 'test'] >ほげ <type 'str'> 6 0 >hoge <type 'str'> 4 サーバ側: $ python server.py listen localhost - - [11/Sep/2005 12:20:38] "POST /RPC2 HTTP/1.0" 200 - <type 'unicode'> 2 ほげ localhost - - [11/Sep/2005 12:20:47] "POST /RPC2 HTTP/1.0" 200 - <type 'str'> 4 hoge localhost - - [11/Sep/2005 12:21:03] "POST /RPC2 HTTP/1.0" 200 -
当初、MLの内容から、コード自体をUTF-8で記述しないといけないのか?と思ってたんだが、そこまでする必要は無く、実際、検証コードも、EUCで記述している。
送受信時、ちと手間な変換作業が発生するが、まぁ 許容範囲でしょう。