是否有办法将我的SOAP Web服务(spring-ws、java)虚拟地用作基于XML的RESTful服务?
我不想用java从头开始将整个SOAP Web服务重写到RESTful中,但我需要使用REST通过iPhone访问它,他们已经有了简单的本地支持。
XMLGateway、Proxys......或一些额外的java代码?既然我的SOAP请求和响应只是一个XML文件,为什么我不能修改它以供REST服务使用?
或者,在不更改应用程序中的任何逻辑和xml解析的情况下,添加jax-rs注解并创建一个rest请求xml是那么容易吗?
我的配置spring文件是这样的:
<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;
}
}
有什么主意吗?
5条答案
按热度按时间mpgws1up1#
Spring-WS只是给bean添加了一些注解,然后你让Spring bean做了大部分繁重的工作。假设你有一些用@Endpoint,@PayloadRoot等注解的类。你应该能够以三种方式之一重用所有这些。
如果您的Spring-WS端点类是适配器模式风格的(例如,您的Endpoint类被注入了一个执行真实的工作的POJO服务),那么您可以做一个类似的适配器风格的Spring MVC控制器(Spring 3.0中存在REST)。
如果直接在业务逻辑类上添加注解,那么理论上,您应该能够添加更多的注解(可能看起来有点忙)。
如果您有POX(而不是SOAP)的Spring-WS bean,那么您也许可以使用一些花哨的URLMap来为它们提供更符合RESTful外观的URL
为了迁移到Spring 3以获得REST支持,添加适当的@RequestMapping和其他注解,将它们公开为REST服务以匹配特定的URL。在添加时,您可能还需要删除旧的@PayloadRoots和@Endpoint,但这可能不是什么大问题。当然,如果您保留旧的Spring-WS注解,您仍然需要在类路径中使用Spring-WS jar。但是只要您没有在Spring文件中使用Spring-WSservlet或任何其他bean,就应该没问题(理论上...)。
最大的难题是:
qco9c6ql2#
通过查看代码,很难判断哪种方法最好。REST和SOAP是想象基于Web的服务接口如何工作的完全不同的方法:SOAP是所有关于方法调用的,而REST是所有关于资源、表示和链接的。要转换,你必须从你的底层抽象API开始。
如果您的基本API是“我给予您一个文档,您给我一个响应文档”,并且除此之外没有任何其他公开内容,那么它就是一个 * 非常 * 面向SOAP的模型。您可以在REST中通过POST一个文档并获得响应来对此建模,但它一点也不优雅。如果您可以将您的界面视为“这是一个总体资源,带有我可以设置的属性,和某些我可以做的操作”,那么Map到REST就容易得多(整个资源表示为一个文档,其中充满了指向各个属性资源和操作的链接,各个属性可以是GET和PUT --也可能是DELETEd --如果需要的话)。但我只是猜测,因为真实的确定它需要查看比所显示的更多的代码。
9o685dep3#
没有什么可以阻止您发送填充了XML的POST,以返回填充了XML的结果。
最简单的方法是捕获来回的SOAP请求,然后简单地将请求转换为一个模板,其中的空白作为参数,然后对生成的XML使用XPath来提取结果。
唯一的缺点是你可能需要SOAPAction头在你的POST中,但很可能不是。
这真的没什么大不了的。如果你有几十个方法,那就更麻烦了。而且,如果你使用SOAP的任何加密部分,那就更麻烦了。但是如果只有几个,最终它只是XML,而且大部分XML都是样板文件,所以从这个Angular 看,这是非常简单的。
附录:
如果您有一个后端逻辑,您希望将其与一个更友好的HTTP服务放在一起,那么JAX-RS可以很容易地做到这一点,但是它需要在服务器端进行编码。
如果您希望使用现有的SOAPWeb服务,那么请忘记等式中的整个SOAP部分,而简单地将其视为使用XML有效负载的HTTPWeb服务。它仍然是SOAP,但您没有在客户端使用任何SOAP工具。您只是在客户端请求上组装XML有效负载(从模板是最简单的,恕我直言),并消费XML有效负载作为结果,并通过HTTP交易这些。
根据您打算调用的现有Web服务上的不同方法的数量,您可以了解所涉及的工作范围。这是一项简单的工作(一旦您可以轻松地查看有效负载),但它仍然是工作。如果您只有几个方法,特别是如果接口是稳定的,不会发生变化,那么只使用原始XML比学习和使用一些新的不熟悉的框架要容易得多。
yhqotfr84#
这就是我如何解决这个问题的,使用Sping Boot + Spring Integration。
cedebl8k5#
如果我们根本不使用spring,也没有@Payload这样的注解,那么应该采取什么方法呢?简单地将xsd生成的类重用为Pojo,并公开rest控制器应该可以解决问题,否则还有更多的问题。