Spyne多服务多目标命名空间场景下使用WsgiMounter整合后返回404错误的解决方法
解决Spyne WsgiMounter整合服务后根路径404的问题
你遇到的404问题其实是WsgiMounter的工作机制导致的——它的作用是将不同的WSGI应用映射到不同的子URL路径,而不是把多个服务合并到同一个根路径下。
问题根源
你用WsgiMounter({"hello": hello, "auth": auth})把两个Spyne Application分别挂载到了/hello/和/auth/子路径,但根路径/并没有关联任何Spyne应用,所以访问http://0.0.0.0:8000/?wsdl时,服务器找不到对应的资源,就返回了404。
直接解决方法:访问对应子路径的WSDL
整合后,两个服务的访问路径需要加上对应的子前缀:
- Hello服务的WSDL:
http://0.0.0.0:8000/hello/?wsdl - Auth服务的WSDL:
http://0.0.0.0:8000/auth/?wsdl
调用接口时也需要使用这些子路径,比如调用Hello的hello方法,请求地址是http://0.0.0.0:8000/hello/。
可选:给根路径添加引导页面
如果你希望根路径也能提供有用的响应(比如展示两个服务的WSDL链接),可以给WsgiMounter添加一个根路径的WSGI应用。比如写一个简单的WSGI函数:
from spyne import ( Application, ServiceBase, rpc, Unicode, ) from spyne.protocol.soap import Soap11 from spyne.server.wsgi import WsgiApplication from spyne.util.wsgi_wrapper import WsgiMounter from wsgiref.simple_server import make_server import logging class Hello(ServiceBase): @rpc(_returns=Unicode) def hello(ctx): return "Hello, World!" class Auth(ServiceBase): @rpc(_returns=Unicode) def authenticate(ctx): return "authenticated!" hello = Application( [Hello], tns="hello_tns", name="hello", in_protocol=Soap11(validator="lxml"), out_protocol=Soap11(), ) auth = Application( [Auth], tns="auth_tns", name="auth", in_protocol=Soap11(validator="lxml"), out_protocol=Soap11(), ) # 根路径的引导WSGI应用 def root_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/html; charset=utf-8')] start_response(status, headers) content = """ <h1>Spyne Services</h1> <ul> <li><a href="/hello/?wsdl">Hello Service WSDL</a></li> <li><a href="/auth/?wsdl">Auth Service WSDL</a></li> </ul> """ return [content.encode('utf-8')] wsgi_mounter = WsgiMounter({ "": root_app, # 根路径映射到引导页面 "hello": WsgiApplication(hello), "auth": WsgiApplication(auth), }) if __name__ == "__main__": logging.basicConfig(level=logging.INFO) logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG) server = make_server("0.0.0.0", 8000, wsgi_mounter) print("Server running on http://0.0.0.0:8000") server.serve_forever()
这样访问http://0.0.0.0:8000/时,会显示一个包含两个服务WSDL链接的页面,用户可以直接点击访问。
内容的提问来源于stack exchange,提问作者Amir Shabani
相关产品推荐
相关产品推荐

