我试图创建两个独立的web服务,都在一个spring部署中,都从相同的xsd模式中生成wsdl,但是将它们路由到两个独立的endpoint,这样我就可以在不同的上下文中以不同的方式处理请求。
前任:
Webservice 1:访问、较低权限和安全约束的子集
Webservice 2:更高权限
<sws:dynamic-wsdl id="spml-readonly"
portTypeName="SpmlReadOnlyService"
locationUri="SpmlReadOnly">
<sws:xsd location="/WEB-INF/xsd/spml/pstc_spmlv2_core.xsd"/>
</sws:dynamic-wsdl>
<sws:dynamic-wsdl id="spml-crud"
portTypeName="SpmlCrudService"
locationUri="SpmlCrud">
<sws:xsd location="/WEB-INF/xsd/spml/pstc_spmlv2_core.xsd"/>
<sws:xsd location="/WEB-INF/xsd/spml/pstc_spmlv2_search.xsd"/>
<sws:xsd location="/WEB-INF/xsd/spml/pstc_spmlv2_batch.xsd"/>
</sws:dynamic-wsdl>
现在,由于两个wsdl都基于相同的xsd,因此请求的“命名空间”和“localPart”在线路上是相同的,无论我点击的是哪个Web服务(/SpmlReadOnly或 /SpmlCrud)。
因此,这就排除了不推荐的PayloadRootQNameEndpointMapping,因为localPart和namespace仍然是相同的,等等,...我当前的配置只是将请求路由到同一个endpoint方法处理程序,我无法区分调用了哪个web服务:
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "lookupRequest")
@ResponsePayload
public Source handleLookupRequest(SoapMessage message) throws Exception {
...
}
我能做的事情是可能的吗?如果xsd是共享的,并且在模式的根部具有相同的命名空间,以及相同的localPart方法请求,是否有办法区分它们并映射到两个不同的endpoint?关于这一点的任何信息都将是有用的!我希望我不必设置两个单独的. war并在服务器上使用自己的代码库单独部署它们!
谢谢,达米安
您需要一些结合了URI
和有效负载根
映射的东西。不幸的是,Spring-Ws没有这样的东西。但是因为它非常具有可扩展性,所以实现这一点非常容易。
TL;速度三角形定位法(dead reckoning)
参见GitHub上的这个分支以获得工作示例
详细信息
您需要创建组合的 URI QName 到 org.springframework.ws.server.endpoint.MethodEndpoint
实例的映射。此外,您还应该尽量减少会复制现有Spring-Ws函数的代码。
因此1)您需要在不使用的情况下显式配置Spring-Ws注释
这是您的要求(使用我的模式):
<ws:dynamic-wsdl id="spml-readonly" portTypeName="SpmlReadOnlyService" locationUri="SpmlReadOnly">
<ws:xsd location="classpath:springws/model/schema.xsd" />
</ws:dynamic-wsdl>
<ws:dynamic-wsdl id="spml-crud" portTypeName="SpmlCrudService" locationUri="SpmlCrud">
<ws:xsd location="classpath:springws/model/schema.xsd" />
<ws:xsd location="classpath:springws/model/schema2.xsd" />
</ws:dynamic-wsdl>
这就是您需要手动完成的所有操作,通常通过以下方式进行配置:
<bean class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
<property name="methodArgumentResolvers">
<list>
<ref local="marshallingPayloadMethodProcessor"/>
</list>
</property>
<property name="methodReturnValueHandlers">
<list>
<ref local="marshallingPayloadMethodProcessor"/>
</list>
</property>
</bean>
<bean id="marshallingPayloadMethodProcessor" class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
<property name="marshaller" ref="marshaller" />
<property name="unmarshaller" ref="marshaller" />
</bean>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPaths">
<list>
<value>springws.model</value>
</list>
</property>
</bean>
这是自定义映射:
<bean class="springws.PathAndPayloadRootAnnotationEndpointMapping" />
2)您应该创建自己的映射
public class PathAndPayloadRootAnnotationEndpointMapping extends PayloadRootAnnotationMethodEndpointMapping
{
@Override
protected QName getLookupKeyForMessage(MessageContext messageContext) throws Exception
{
String urlPart = "";
QName payloadRootPart = super.getLookupKeyForMessage(messageContext);
TransportContext transportContext = TransportContextHolder.getTransportContext();
if (transportContext != null) {
WebServiceConnection connection = transportContext.getConnection();
if (connection != null && connection instanceof HttpServletConnection) {
String requestURI = ((HttpServletConnection)connection).getHttpServletRequest().getRequestURI();
String contextPath = ((HttpServletConnection)connection).getHttpServletRequest().getContextPath();
urlPart = requestURI.substring(contextPath.length());
}
}
return new QName(payloadRootPart.getNamespaceURI(), urlPart + "/" + payloadRootPart.getLocalPart());
}
@Override
protected List<QName> getLookupKeysForMethod(Method method)
{
List<QName> result = new ArrayList<QName>();
RequestMapping rm = AnnotationUtils.findAnnotation(method.getDeclaringClass(), RequestMapping.class);
String urlPart = rm == null || rm.value().length != 1 ? "" : rm.value()[0];
List<QName> methodPart = super.getLookupKeysForMethod(method);
for (QName qName : methodPart) {
result.add(new QName(qName.getNamespaceURI(), urlPart + "/" + qName.getLocalPart()));
}
return result;
}
}
注释,但有人认为这是一个黑客,可能会创建他/她自己的注释。它扩展了< code > org . spring framework . ws . server . endpoint . mapping . payloadrootannotationmethodenpointmapping
。它所做的只是用从endpointURI提取的信息扩展消息的键(有效负载根元素的QNames)。为此,我使用了Spring的< code > @ org . Spring framework . web . bind . annotation . request mapping
所以对于这样的endpoint:
@org.springframework.ws.server.endpoint.annotation.Endpoint
@RequestMapping("/ws/SpmlReadOnly")
public class Endpoint1
{
@ResponsePayload
@PayloadRoot(namespace = "urn:test", localPart = "method1Request")
public Response2 method(@RequestPayload Request1 request) throws Exception
{
return new Response2("e1 m1");
}
}
关键不在于:
namespace = urn:test
localName = method1Request
但是这个:
namespace = urn:test
localName = /ws/SpmlReadOnly/method1Request
< code >受保护的QName getLookupKeyForMessage(message context message context)方法确保映射URI独立于应用程序部署的WAR上下文。
我发送一个POST请求,从一家运输公司生成AWB。为了做到这一点,我必须通过SOAP API POST请求发布多个数据条目。下面的XML是类似的,这是必需的(我已经简化了,否则它要求超过30个参数) 我是SOAP新手,请帮助我朝着正确的方向前进,我甚至非常感谢上面的XML代码,因为它有助于更好地理解。
我用的是spring soap ws。 我有以下对应于复杂类型的JAXB域类 我有以下带有@XmlRegistry注释的类 以下是endpoint 当我发出 Soap 请求时,我正在使用 soap 请求中的终结点中给出NAMESPACE_URI。 在这里,在这种情况下,我得到以下回应 如果我使用"超文本传输协议://命名空间/url"作为NAMESPACE_URI在endpoint和肥皂请求我得到
问题内容: 我有一个这样的架构层次结构: 一个文件夹中的所有文件都具有相同的命名空间。 现在,我想将名称空间映射到特定的Java包(我不能更改名称空间)。 我找到了将架构绑定到程序包的解决方案。但是然后我必须为每个xsd文件创建一个条目: 有没有一种方法可以直接定义名称空间和程序包名称之间的绑定? 另一种方法是在maven中定义包: 但是然后我必须为每个文件夹创建一个执行,这并不是我真正想要的。
问题内容: 我正在尝试使用RSA 7.5和Websphere 7服务器开发IBM JAX_WS Web服务。因为我是一个初学者,所以我遵循Java类优先方法,即首先创建Java类,然后生成WSDL文件。 当我尝试创建wsdl文件时,出现异常: java.security.PrivilegedActionException:com.sun.xml.internal.bind.v2.runtime.I
问题内容: 我正在用C#编写.NET Framework 3.5。 我正在尝试将某些Json解析为JObject。 Json如下: 当我尝试将此Json解析为JObject时,JObject仅了解LargeBox。SmallBox和MedBox的信息丢失。显然,这是因为它将“ TBox”解释为一个属性,并且该属性已被覆盖。 我从Delphi编码的服务中收到此Json。我正在尝试为该服务创建C#代理