Spyne:为什么我收到 json 请求的空响应?
Spyne: Why am I getting empty responses for json requests?
我有一个正在运行的应用程序,它接受 SOAP 请求、处理请求、将 SOAP 请求转发给 API、处理响应,然后将响应转发给客户端。
我正在尝试更改此应用程序,以便它在我的应用程序和客户端之间 JSON 但仍然在 API 和我的应用程序
之间使用 SOAP
现在,它可以成功接受来自客户端的 JSON 请求和 send/receive 带有 API 的 SOAP。但是,对客户端的所有响应都是空的。
我收到非空响应的唯一情况是我的 JSON 请求出现验证错误。
这里有一些可能相关的代码
app = Application([MyServer],
MY_NAMESPACE,
in_protocol=JsonDocument(validator='soft'),
out_protocol=JsonDocument())
application_server = csrf_exempt(MyDjangoApplication(app))
MyDjangoApplication 的定义
class MyDjangoApplication(DjangoApplication):
def __call__(self, request, *args, **kwargs):
retval = self.HttpResponseObject()
def start_response(status, headers):
# Status is one of spyne.const.http
status, reason = status.split(' ', 1)
retval.status_code = int(status)
for header, value in headers:
retval[header] = value
environ = request.META.copy()
if request.method == 'POST':
response = self.handle_rpc(environ, start_response)
else:
home_path = reverse('proxy:list_method')
uri = MY_ENDPOINT_URL or request.build_absolute_uri(home_path)
# to generate wsdl content
response = self._WsgiApplication__handle_wsdl_request(environ, start_response, uri)
if request.path == home_path and _is_wsdl_request(environ):
fn = None
elif 'method_name' in kwargs:
fn = view_method
else:
fn = list_method
if fn:
return fn(request, app=self, *args, **kwargs)
self.set_response(retval, response)
return retval
MyServer 的定义
class MyServer(ServiceBase):
@rpc(MyTestMethodRequest, Sign, **method(_returns=MyTestMethodResponse))
@check_method()
def TestMethod(ctx, request, signature):
response = {
'Data': "test"
}
return response
MyTestMethodRequest、MyTestMethodResponse 的定义:
class MyTestMethodRequest(ComplexModel):
__namespace__ = MY_NAMESPACE
MyString = String(encoding=STR_ENCODING)
class MyTestMethodResponse(ComplexModel):
__namespace__ = MY_NAMESPACE
Data = String(encoding=STR_ENCODING)
check_method的定义:
def check_method(error_handler=None):
def _check_method(func):
method_name = func.__name__
def __check_method(ctx, request, signature, *args, **kwargs):
if hasattr(request, '__dict__'):
request = request.__dict__
if hasattr(signature, '__dict__'):
signature = signature.__dict__
response = func(ctx, request or {}, signature or {}, *args, **kwargs)
# setting output protocol
output_message = generate_out_string(ctx, [response])
return response
__check_method.__name__ = method_name
__check_method.__doc__ = func.__doc__
return __check_method
return _check_method
generate_out_string的定义:
def generate_out_string(ctx, objects):
ctx.out_protocol = ctx.in_protocol
return _generate_out_string(ctx, objects)
def _generate_out_string(ctx, objects):
protocol = ctx.out_protocol
ctx.out_object = objects
protocol.serialize(ctx, protocol.RESPONSE)
protocol.create_out_string(ctx)
out_string = list(ctx.out_string)
return out_string[0] if out_string else ''
注意:这些定义中的大部分已被简化(我删除了我认为不相关的行)
查看您发布的代码,我不能说我理解围绕参数的所有这些附加装饰器和修饰符有什么好处。
删除它们应该可以解决所有问题。
所以让:
class MyTestMethodRequest(ComplexModel):
__namespace__ = MY_NAMESPACE
MyString = Unicode
class MyTestMethodResponse(ComplexModel):
__namespace__ = MY_NAMESPACE
Data = Unicode
假设您有以下服务:
class MyService(ServiceBase):
@rpc(MyTestMethodRequest, Sign, _returns=MyTestMethodResponse)
def TestMethod(ctx, request, signature):
return MyTestMethodResponse(data="test")
您可以拥有:
app_json = Application([MyService],
MY_NAMESPACE,
in_protocol=JsonDocument(validator='soft'),
out_protocol=JsonDocument())
和
app_soap = Application([MyService],
MY_NAMESPACE,
in_protocol=Soap11(validator='lxml'),
out_protocol=Soap11())
又可以像往常一样传递给 DjangoApplication
。:
app_json_dja = csrf_exempt(DjangoApplication(app_json))
app_soap_dja = csrf_exempt(DjangoApplication(app_soap))
反过来你可以安装在 Django 的 url 路由器中。
希望对您有所帮助!
我有一个正在运行的应用程序,它接受 SOAP 请求、处理请求、将 SOAP 请求转发给 API、处理响应,然后将响应转发给客户端。
我正在尝试更改此应用程序,以便它在我的应用程序和客户端之间 JSON 但仍然在 API 和我的应用程序
之间使用 SOAP现在,它可以成功接受来自客户端的 JSON 请求和 send/receive 带有 API 的 SOAP。但是,对客户端的所有响应都是空的。
我收到非空响应的唯一情况是我的 JSON 请求出现验证错误。
这里有一些可能相关的代码
app = Application([MyServer],
MY_NAMESPACE,
in_protocol=JsonDocument(validator='soft'),
out_protocol=JsonDocument())
application_server = csrf_exempt(MyDjangoApplication(app))
MyDjangoApplication 的定义
class MyDjangoApplication(DjangoApplication):
def __call__(self, request, *args, **kwargs):
retval = self.HttpResponseObject()
def start_response(status, headers):
# Status is one of spyne.const.http
status, reason = status.split(' ', 1)
retval.status_code = int(status)
for header, value in headers:
retval[header] = value
environ = request.META.copy()
if request.method == 'POST':
response = self.handle_rpc(environ, start_response)
else:
home_path = reverse('proxy:list_method')
uri = MY_ENDPOINT_URL or request.build_absolute_uri(home_path)
# to generate wsdl content
response = self._WsgiApplication__handle_wsdl_request(environ, start_response, uri)
if request.path == home_path and _is_wsdl_request(environ):
fn = None
elif 'method_name' in kwargs:
fn = view_method
else:
fn = list_method
if fn:
return fn(request, app=self, *args, **kwargs)
self.set_response(retval, response)
return retval
MyServer 的定义
class MyServer(ServiceBase):
@rpc(MyTestMethodRequest, Sign, **method(_returns=MyTestMethodResponse))
@check_method()
def TestMethod(ctx, request, signature):
response = {
'Data': "test"
}
return response
MyTestMethodRequest、MyTestMethodResponse 的定义:
class MyTestMethodRequest(ComplexModel):
__namespace__ = MY_NAMESPACE
MyString = String(encoding=STR_ENCODING)
class MyTestMethodResponse(ComplexModel):
__namespace__ = MY_NAMESPACE
Data = String(encoding=STR_ENCODING)
check_method的定义:
def check_method(error_handler=None):
def _check_method(func):
method_name = func.__name__
def __check_method(ctx, request, signature, *args, **kwargs):
if hasattr(request, '__dict__'):
request = request.__dict__
if hasattr(signature, '__dict__'):
signature = signature.__dict__
response = func(ctx, request or {}, signature or {}, *args, **kwargs)
# setting output protocol
output_message = generate_out_string(ctx, [response])
return response
__check_method.__name__ = method_name
__check_method.__doc__ = func.__doc__
return __check_method
return _check_method
generate_out_string的定义:
def generate_out_string(ctx, objects):
ctx.out_protocol = ctx.in_protocol
return _generate_out_string(ctx, objects)
def _generate_out_string(ctx, objects):
protocol = ctx.out_protocol
ctx.out_object = objects
protocol.serialize(ctx, protocol.RESPONSE)
protocol.create_out_string(ctx)
out_string = list(ctx.out_string)
return out_string[0] if out_string else ''
注意:这些定义中的大部分已被简化(我删除了我认为不相关的行)
查看您发布的代码,我不能说我理解围绕参数的所有这些附加装饰器和修饰符有什么好处。
删除它们应该可以解决所有问题。
所以让:
class MyTestMethodRequest(ComplexModel):
__namespace__ = MY_NAMESPACE
MyString = Unicode
class MyTestMethodResponse(ComplexModel):
__namespace__ = MY_NAMESPACE
Data = Unicode
假设您有以下服务:
class MyService(ServiceBase):
@rpc(MyTestMethodRequest, Sign, _returns=MyTestMethodResponse)
def TestMethod(ctx, request, signature):
return MyTestMethodResponse(data="test")
您可以拥有:
app_json = Application([MyService],
MY_NAMESPACE,
in_protocol=JsonDocument(validator='soft'),
out_protocol=JsonDocument())
和
app_soap = Application([MyService],
MY_NAMESPACE,
in_protocol=Soap11(validator='lxml'),
out_protocol=Soap11())
又可以像往常一样传递给 DjangoApplication
。:
app_json_dja = csrf_exempt(DjangoApplication(app_json))
app_soap_dja = csrf_exempt(DjangoApplication(app_soap))
反过来你可以安装在 Django 的 url 路由器中。
希望对您有所帮助!