繁体   English   中英

如何在Spring Soap Web服务中注册自定义端点映射

[英]How to register a custom Endpoint Mapping in Spring Soap web services

我正在实现与某些旧版SOAP服务进行交互的SOAP客户端。

所有SOAP正文请求都具有相同的格式,如下所示:

<soap:Body>
   <execute>
      <msg>
      </msg>
   </execute>
</soap:Body>

作为内容,msg元素支持任何 XML标记的列表,因此我可以在msg内部发送任何类型的元素:订单,客户,联系人等。

所有请求还具有相同的操作名称。

由于上述限制/方面,如果我使用spring的PayloadRootAnnotationMethodEndpointMapping ,由于soap主体中的根元素对于所有请求都是相同的,则每个请求都将属于Endpoint的相同方法。 如果我使用spring的SoapActionAnnotationMethodEndpointMapping ,由于每个请求的操作都相同,因此所有请求将再次属于同一方法。

我在请求中唯一不同的是请求URI。 它根据我正在调用的操作的名称而改变。 像: http:// host:port / services / Operation1?Wsdlhttp:// host:port / services / Operation2?Wsdl

我的想法是为每种类型的请求提供一个端点。 例如:与产品相关的所有请求都将放入“ ProductsEndpoint”。 我想创建一个自定义的端点映射,以扩展Spring AbstractEndpointMapping。 在我的实现中,我将根据URI决定要调用的端点。

但是,如何在Spring的端点映射链中注册我的自定义端点映射?

最好的祝福

如果有人有像我上面解释的那样的请求,这里就是我决定要做的...

我创建了一个扩展spring org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor的类MultipleMarshallersPayloadMethodProcessor。 这是负责编组和解组参数的类。 在此类中,我定义了一个java.util.map,它将给定的URL与特定的Marshaller关联。 如果当前URL请求不是映射中的键,则它将使用MarshallingPayloadMethodProcessor类提供的默认Marshaller。

要将类注册为spring bean:

<bean id="marshallingPayloadMethodProcessor"
        class="br.com.tim.fiber.middleware.services.server.helpers.MultipleMarshallersPayloadMethodProcessor">
        <constructor-arg ref="defaultMarshaller" />
        <property name="otherMarshallers">
            <map>
                <entry key="/Operation1?wsdl" value-ref="operation1Marshaller"></entry>
                <entry key="/Operation2?wsdl" value-ref="operation2Marshaller"></entry>
            </map>
        </property>
    </bean>

还有一个编组员的例子:

<bean id="operation1Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPaths">
            <list>
                <value>com.app.dtos.operation1</value>
                <value>com.app.dtos.common</value>
            </list>
        </property>
    </bean>

通过此设置,我可以根据URL封送和取消封送任何请求。 然后,我使用了Facade设计模式通过一个接收所有请求的单一方法来创建SOAP端点。 该方法仅检查URL并委托给特定的端点。

@Endpoint
public class FacadeEndpoint {
    private static final String NAMESPACE_URI = "http://my.namespace.com/services";
    @Autowired
    private RequesEndpointURLExtractor requestUrlExtractor;
    @Autowired
    private OrdersEndpoint ordersEndpoint;

    @SuppressWarnings("unchecked")
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "execute")
    @ResponsePayload
    public ExecuteResponse dispatch(@RequestPayload Execute request) {
        String serviceURL = this.requestUrlExtractor.getCurrentURL();
        ExecuteResponse response = null;

        if (serviceURL.equals(ServiceRequestsEndpoint.CREATE_ENDPOINT_URI)) {
            Operation1DTO serviceRequest = (Operation1DTO) request.getMsg().getAnies().get(0);
}
...
}

RequestEnpointURLExtractor只是一个从请求中提取完整URL的spring bean。

@Component
public class RequesEndpointURLExtractor {

    public String getCurrentURL() {
        TransportContext ctx = TransportContextHolder.getTransportContext();
        HttpServletRequest httpServletRequest = ((HttpServletConnection) ctx.getConnection()).getHttpServletRequest();

        String pathInfo = httpServletRequest.getPathInfo();
        String queryString = httpServletRequest.getQueryString();

        return pathInfo + "?" + queryString;
    }
}

我可以创建一个与URL关联的自定义批注,然后将该批注用于在配置了URL的情况下处理请求的方法。 那将是一个更干净的解决方案,而不是我拥有的if / else if阶梯。

但是,由于这仅适用于简单的模型服务器,因此if / else if阶梯并不是什么大问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM