2015-07-12 95 views
27

我想用python SimpleHTTPServer構建一個簡單的REST服務器。我在閱讀帖子信息時遇到問題。請讓我知道如果我做對了。從SimpleHTTPServer讀取JSON發佈數據

from SimpleHTTPServer import SimpleHTTPRequestHandler 
import SocketServer 
import simplejson 

class S(SimpleHTTPRequestHandler): 
    def _set_headers(self): 
     self.send_response(200) 
     self.send_header('Content-type', 'text/html') 
     self.end_headers() 

    def do_GET(self): 
     print "got get request %s" % (self.path) 
     if self.path == '/': 
      self.path = '/index.html' 
      return SimpleHTTPRequestHandler.do_GET(self) 

    def do_POST(self): 
     print "got post!!" 
     content_len = int(self.headers.getheader('content-length', 0)) 
     post_body = self.rfile.read(content_len) 
     test_data = simplejson.loads(post_body) 
     print "post_body(%s)" % (test_data) 
     return SimpleHTTPRequestHandler.do_POST(self) 

def run(handler_class=S, port=80): 
    httpd = SocketServer.TCPServer(("", port), handler_class) 
    print 'Starting httpd...' 
    httpd.serve_forever() 

index.html文件

<html> 
<title>JSON TEST PAGE</title> 
<head> 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
<script type="text/javascript"> 

JSONTest = function() { 

var resultDiv = $("#resultDivContainer"); 

$.ajax({ 
    url: "http://128.107.138.51:8080", 
    type: "POST", 
    data: {txt1: $("#json_text").val()}, 
    dataType: "json", 
    success: function (result) { 
     switch (result) { 
      case true: 
       processResponse(result); 
       break; 
      default: 
       resultDiv.html(result); 
     } 
    }, 
    error: function (xhr, ajaxOptions, thrownError) { 
    alert(xhr.status); 
    alert(thrownError); 
    } 
}); 
}; 

</script> 
</head> 
<body> 

<h1>My Web Page</h1> 
<div id="resultDivContainer"></div> 
<form> 
<textarea name="json_text" id="json_text" rows="50" cols="80"> 
[{"resources": {"dut": "any_ts", "endpoint1": "endpoint", "endpoint2": "endpoint"}}, 
{"action": "create_conference", "serverName": "dut", "confName": "GURU_TEST"}] 
</textarea> 
<button type="button" onclick="JSONTest()">Generate Test</button> 
</form> 
</body> 
</html> 

的SimpleJson無法從POST消息加載JSON。我不熟悉網絡編碼,我甚至不確定我所做的是否適合創建簡單的REST API服務器。 我感謝您的幫助。

+1

也請讓我知道這是不是要走,如果有一個Django是你唯一的選擇方式。 –

回答

32

感謝matthewatabet的克萊因的想法。我想通過BaseHTTPHandler實現它。下面的代碼。

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
import SocketServer 
import simplejson 
import random 

class S(BaseHTTPRequestHandler): 
    def _set_headers(self): 
     self.send_response(200) 
     self.send_header('Content-type', 'text/html') 
     self.end_headers() 

    def do_GET(self): 
     self._set_headers() 
     f = open("index.html", "r") 
     self.wfile.write(f.read()) 

    def do_HEAD(self): 
     self._set_headers() 

    def do_POST(self): 
     self._set_headers() 
     print "in post method" 
     self.data_string = self.rfile.read(int(self.headers['Content-Length'])) 

     self.send_response(200) 
     self.end_headers() 

     data = simplejson.loads(self.data_string) 
     with open("test123456.json", "w") as outfile: 
      simplejson.dump(data, outfile) 
     print "{}".format(data) 
     f = open("for_presen.py") 
     self.wfile.write(f.read()) 
     return 


def run(server_class=HTTPServer, handler_class=S, port=80): 
    server_address = ('', port) 
    httpd = server_class(server_address, handler_class) 
    print 'Starting httpd...' 
    httpd.serve_forever() 

if __name__ == "__main__": 
    from sys import argv 

if len(argv) == 2: 
    run(port=int(argv[1])) 
else: 
    run() 

而且相應的HTML頁面

<form action="/profile/index/sendmessage" method="post" enctype="application/x-www-form-urlencoded"> 
<div class="upload_form"> 
    <dt id="message-label"><label class="optional" for="message">Enter Message</label></dt> 
    <dd id="message-element"> 
    <textarea cols="80" rows="50" id="message" name="message"> 
[{"resources": {"dut": "any_ts", "endpoint1": "multistream_endpoint", "endpoint2": "multistream_endpoint"}}, 

{"action": "create_conference", "serverName": "dut", "conferenceName": "GURU_SLAVE_TS"}, 

{"action": "dial_out_ep", "serverName": "dut", "confName": "GURU_SLAVE_TS", "epName": "endpoint1"} 
] 
     </textarea></dd> 
    <dt id="id-label">&nbsp;</dt> 
    <dd id="id-element"> 
    <input type="hidden" id="id" value="145198" name="id"></dd> 
    <dt id="send_message-label">&nbsp;</dt> 
    <dd id="send_message-element"> 
    <input type="submit" class="sendamessage" value="Send" id="send_message" name="send_message"></dd> 
</div> 
</form> 

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
<script type="text/javascript"> 
$("input.sendamessage").click(function(event) { 
event.preventDefault(); 

var message = $('textarea#message').val(); 
var id  = $('input#id').val(); 
url = "http://128.107.138.51:8080" 

var posting = $.post(url, message) 

posting.done(function(data) { 
    alert(message); 
}); 
}); 


</script> 
8

SimpleHTTPRequestHandler不支持POST。這確實很簡單。看看Klein的服務器功能更全面一些。

有一個JSON PUT(相當接近POST)的例子在這裏: https://pypi.python.org/pypi/klein/0.2.3

import json 

from klein import Klein 


class ItemStore(object): 
    app = Klein() 

    def __init__(self): 
     self._items = {} 

    @app.route('/') 
    def items(self, request): 
     request.setHeader('Content-Type', 'application/json') 
     return json.dumps(self._items) 

    @app.route('/<string:name>', methods=['PUT']) 
    def save_item(self, request, name): 
     request.setHeader('Content-Type', 'application/json') 
     body = json.loads(request.content.read()) 
     self._items[name] = body 
     return json.dumps({'success': True}) 

    @app.route('/<string:name>', methods=['GET']) 
    def get_item(self, request, name): 
     request.setHeader('Content-Type', 'application/json') 
     return json.dumps(self._items.get(name)) 


if __name__ == '__main__': 
    store = ItemStore() 
    store.app.run('localhost', 8080) 
+0

感謝您的鏈接。我也認爲它可以用BaseHTTPHandler完成。 –