Spring专题

使用Spring Webservices建立SOAP服务代理

使用Spring Webservices建立SOAP服务代理源码下载

ws-proxy 模块是系统之间SOAP消息的中继层,协调两个方向:内部的服务(in bound方式)和外部服务(作为客户端,outbound 方式),. 相比传统的http的forward/reverse 代理 ,它是更高层次,处理SOAP消息。

在 outbound 方式我们的内部服务经常使用wsproxy作为一个http forward代理. wsproxy将处理传送接受到的消息到真正目标,而在inbound方式它将作为一个反转代理,接受外部客户端的消息,然后传递他们给我们内部的服务。

下面是一个SOA内部流程事宜图:

soa和bpm

 

转发forward代理是客户端明确配置指定的目标URL 。 HTTP的客户端堆栈将消息发送到配置的代理服务器,通过HTTP头( Host头)发送所需??的目标主机的主机/端口。然后代理服务器将请求转发给所需的目标主机/端口,并返回给客户端的响应处理。因此,代理服务在HTTP主机头基础组合成目标URL的主机和端口 。对于路径,它将使用从从客户端请求接收的路径。

反向reverse 代理(从客户端的角度)是作为实际目标服务器。客户端不知道任何代理,既不需要配置什么特别的东西。客户端使用的是将反向代理的URL作为目标URL 。反向代理将能够拦截从客户端和内网转发到实际的目标的消息。反向代理将需要额外的配置目标服务的URL(主机,端口和路径) ,例如如果不能从请求或HTTP标头导出的主机/端口。

当使用这个模块,仍然可以实现一个实际的HTTP反向代理TLS卸载或其它运输用途的界限。对于外部呼入的流量(消息来自外部往内部服务的客户端)的wsproxy模块将仅仅是第二反向代理传入的请求。对于内部对外交通(消息来自内部客户端发往外部端点)的URL的HTTP反向代理将被配置为特定服务上wsproxy模块的目标URL 。

wsproxy的功能之一是集中关注。我们的目标是,SOAP消息流量可以拦截。这样我们就可以实现特定功能,如:审计日志,监控,门禁,信息安全,这样我们创建了一个集中统一的地方,不必重新为每个应用程序来实现处理这些要求。

 

webservice

 

选择Spring的web服务,是因为没有复杂的基础设施或设计理解。它也具有很高的可扩展性,并提供再利用我们的要求在适当的水平。

一些现有的解决方案在那里,可以做到这一点甚至更多。他们经常伴随XML安全网关的名称和软件包。你还是得写自己的代码,而且需要配置,这些解决方案是得不偿失。事实是,他们不都免费(至少可以这样说) ,你仍然需要有人用正确的配置和维护他们的技能。而我们只要使用Spring Web服务的代码就很容易做到。

设计的初衷:

1.outbound出站模式需要被自由配置成标准用法。这意味着,当需要访问一个新的外部服务,我们的代理中继无需额外的配置。

2.消息通过网关需要登录。无需额外配置应记录整个消息。或者,我们需要能够配置更细粒度的哪些部分需要记录。

3.对于(主要是外部)出站通信,我们应该能够使用预配置的主机(现有的反向代理或实际的端点)配置一个正向代理覆盖目标。

4.模块必须能够在没有另外专门负责安全模块地情况下将消息转发安全转发。

 

图中有三个组件, endpoint 端点将作为消息接收者然后发给wsproxy,forwarder, 转发器将消息中继给目标,最后拦截器链条是一些钩子,在其中我们能够拦截消息做一些事情,如审计日志,监控。

Spring Web Services有三个组件;endpoint端点是org.springframework.ws.server.endpoint.annotation.Endpoint实现 org.springframework.ws.server.endpoint.MessageEndpoint 能够接受消息. 转发器使用 org.springframework.ws.client.core.WebServiceTemplate ,而拦截器链是 org.springframework.ws.client.support.interceptor.ClientInterceptor 和org.springframework.ws.server.EndpointInterceptor。消息安全使用 WSS4J,

“inbound chain”.是介入客户端和wsproxy. 而“outbound chain”是介于wsproxy和目标endpoint. 如果我们有一个内部客户端通wsproxy访问外部端点。当消息被wsproxy接受,inbound chain将被调用。当wsproxy将消息中继给目标端点,outbound chain将被激活调用。

Spring有两个接口来分辨拦截器操作的是哪边,org.springframework.ws.server.EndpointInterceptor操作的是端点endpoint这边拦截, 对于 wsproxy这是inbound.

org.springframework.ws.client.support.interceptor.ClientInterceptor 操作的是客户端这边,对于wsproxy 这是 outbound. wsproxy 既可以作为endpoint也可以作为客户端client. However, “client”客户端意味服务的客户端,而 “endpoint”是实际真正目标服务

该代码使用步骤:

  • 设置一个基于端点的正常soap
  • 部署 wsproxy
  • 使用 web services客户端通过wsproxy访问端点服务endpoint

 

首先我们编制一个客户端代码:

public class SimpleEndpoint {

public static void main(String args[]) {
Endpoint.publish("http://localhost:9999/simple", new SimpleWebServiceEndpoint());
}

@WebService
public static class SimpleWebServiceEndpoint {
public Date getCurrentDate(String randomParameter) {
return new Date();
}
}
}

将wsproxy 部署到tomcat 7等服务器中,没有额外配置,客户端使用soap-ui ,也可以使用Curl。

在soap-ui中我们创建一个项目,暴露服务:

下面在soap-ui配置wsproxy 作为转发forward代理:

soapui的配置文化在这里

访问ws-proxy/simple将导致转发到http://localhost:999/simple,能得到如下结果:

SOA服务