You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Python Tornado的POST方法中接收JSON并更新传感器参数

解决Tornado POST方法接收JSON的500错误问题

我来帮你搞定这个Tornado POST请求的问题!你遇到的500错误大概率是之前注释代码里的拼写错误加上缺少异常处理导致的,下面一步步帮你修复并实现需求。

先排查核心问题

  • 拼写错误:你注释的prepare方法里把headers写成了haders,这会直接抛出AttributeError,触发500错误
  • 缺少异常处理:没有处理JSON解析失败、请求格式不对、缺少必要字段的情况,这些未捕获的异常都会导致服务器报错
  • 全局变量使用:虽然flow_status暂时能用,但后续建议用更安全的方式传递(比如依赖注入或全局存储类)

修复后的完整代码

import tornado.web
import tornado.httpserver
import tornado.ioloop
import tornado.options
from tornado.ioloop import PeriodicCallback
import json
# 假设你的FlowController类已正确定义,替换成实际导入路径
from your_module import FlowController

# 全局变量,后续可优化
flow_status = []

def get_sql_status():
    # 保留你从SQL读取状态的逻辑,这里用示例数据占位
    global flow_status
    flow_status = ["2024-05-20 12:00:00", "192.168.1.100", 25.0, 40.0, 23.5]

class Current(tornado.web.RequestHandler):
    def get(self):
        global flow_status
        time = flow_status[0]
        ip = flow_status[1]
        rate = flow_status[2]
        setp = flow_status[3]
        tempc = flow_status[4]
        status = {
            "flow_controller": {
                "time": time,
                "ip": ip,
                "rate_sccm": rate,
                "setpoint": setp,
                "temperature_c": tempc,
            }
        }
        self.write(status)

class Update(tornado.web.RequestHandler):
    def prepare(self):
        # 修复拼写错误:headers -> headers
        content_type = self.request.headers.get("Content-Type", "")
        if content_type.startswith("application/json"):
            try:
                self.json_args = json.loads(self.request.body)
            except json.JSONDecodeError:
                # JSON格式错误,返回400错误
                self.set_status(400)
                self.write({"error": "Invalid JSON format"})
                self.finish()
        else:
            # 请求格式不符,返回400错误
            self.set_status(400)
            self.write({"error": "Content-Type must be application/json"})
            self.finish()

    def post(self):
        # 检查是否存在setpoint字段
        if "setpoint" not in self.json_args:
            self.set_status(400)
            self.write({"error": "Missing 'setpoint' field in JSON"})
            return
        
        try:
            # 转换为浮点型
            setpoint = float(self.json_args["setpoint"])
        except ValueError:
            self.set_status(400)
            self.write({"error": "'setpoint' must be a valid number"})
            return
        
        try:
            # 连接传感器并更新设定值
            flowMKS = FlowController(flow_status[1])
            flowMKS.set(setpoint)
            # 返回成功响应
            self.write({"success": True, "message": f"Setpoint updated to {setpoint}"})
        except Exception as e:
            # 处理传感器操作失败的情况
            self.set_status(500)
            self.write({"error": f"Failed to update setpoint: {str(e)}"})

if __name__ == '__main__':
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers=[(r'/', Current), (r'/flow_post', Update)]
    )
    http_server = tornado.httpserver.HTTPServer(app)
    # 优先用命令行参数的port,默认8888
    http_server.listen(tornado.options.options.port if hasattr(tornado.options.options, 'port') else 8888)
    PeriodicCallback(get_sql_status, 500).start()
    tornado.ioloop.IOLoop.current().start()

关键修复说明

  1. 修正拼写错误:把self.request.haders改为self.request.headers,这是触发500错误的直接原因
  2. 添加异常处理
    • prepare阶段捕获JSON解析错误,返回400错误而非服务器内部报错
    • 校验请求的Content-Type,确保是application/json格式
    • post方法里检查setpoint字段是否存在,以及能否转换为浮点数,避免类型错误
    • 捕获传感器操作的异常,返回友好的错误提示
  3. 统一响应格式:所有响应(包括错误)都用JSON格式,方便客户端处理

测试方法

curl命令测试POST请求:

curl -X POST -H "Content-Type: application/json" -d '{"setpoint":45.5}' http://localhost:8888/flow_post

正常情况下会返回:

{"success": true, "message": "Setpoint updated to 45.5"}

内容的提问来源于stack exchange,提问作者unmanned15

火山引擎 最新活动