使用Mule ESB建立Web Service的Proxy

如今開發的一個項目要求使用Mule ESB爲一個已有的系統的Web Service接口作代理接口,客戶端調用原來Web Service接口的代碼要求不作大的改動,只修改調用Web Service的url地址爲Mule ESB代理接口的url地址。html

這個要求看起來很簡單,可是實現起來發現有兩個問題:java

1)如何經過Mule ESB的Http控件暴露已有Web Service接口的描述文件?web

也就是說原來描述文件的地址是http://[target ip]:[target port]/service?wsdl,通過http控件後將變成spring

http://[new ip]:[new port]/newservice?wsdl,並且wsdl文件的內容不能改變。apache

2)如何將Mule ESB接口接收的Soap報文發送到實際的Web Service地址,獲得實際結果。服務器

第一個問題我使用CXF Component組件的Proxy Service類型進行配置。app

我建立了兩個Web Service服務,一個是使用Apache CXF搭建的Web Service,一個是使用Asp.net搭建的Web Servicejsp

1.1 Apache CXF Web Service wsdl代理

使用Apache CXF搭建的Web Service只有一個HelloService,主要的類文件和配置文件以下:ide

package com.rick.service;

import javax.jws.WebParam;

public interface HelloService {
	
	String sayHello(@WebParam(name="name") String name);
}
package com.rick.service.impl;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

import org.springframework.stereotype.Component;

import com.rick.service.HelloService;

@Component("helloService")
@WebService
public class HelloServiceImpl implements HelloService {

	@Override
	@WebMethod(action="sayHello")  
	public String sayHello(@WebParam(name="name") String name) {		
		return "Hello world," +name;
	}
}

applicationContext.xmlurl

<?xml version="1.0" encoding="UTF-8"?>   
<beans xmlns="http://www.springframework.org/schema/beans"   
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="   
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd 
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">   
         
    <!-- import CXF configuration files -->
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
    
    <context:component-scan base-package="com.rick.service" />

    <jaxws:endpoint implementor="#helloService" address="hello"/>
	
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>WsDemo</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
      
    <!-- Spring listener -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
     <servlet-name>CXFServlet</servlet-name> 
     <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> 
    </servlet> 
      
    <servlet-mapping> 
       <servlet-name>CXFServlet</servlet-name> 
       <url-pattern>/webservice/*</url-pattern> 
    </servlet-mapping>
</web-app>

 

Web Service配置在一個Web Application中,在Eclipse EE的Tomcat Server啓動後的Web Service wsdl文件訪問地址是:

http://localhost:8080/WsDemo/webservice/hello?wsdl

具體內容以下圖所示

咱們新建一個Mule Project項目WsDemoProxy

在WsDemoProxy項目中,拖拽一個Http Listener和CXF Component組件

Http Listener組件是入口,配置以下圖所示

Http訪問端口爲8081,訪問Path爲/wsdemoproxy

CXF Component配置爲Proxy Service,配置以下圖所示

其中Namespace使用wsdl文件的targetNamespace值,Service使用wsdl:service節點的name屬性值。

在[Advanced] Tab中設置實際的WSDL地址,這裏可使用在線的wsdl地址,也可使用本地的wsdl文件地址,本項目使用前者。

啓動WsDemoProxy項目,訪問http://localhost:8081/wsdemoproxy?wsdl,咱們能夠看到顯示WsDemo項目的wsdl描述文件,代表使用CXF Component 代理CXF搭建的Web Service wsdl成功。

1.2 Asp.net Web Service wsdl代理

我使用Visual Studio 2008建立一個Asp.net Web Service

這個Web Service服務有兩個方法,HelloWorld()和addMethod(int, int),咱們設置它的啓動端口爲8888,啓動後界面以下:

對應的wsdl界面以下:

 

新建一個Mule ESB項目webservice1proxy,與wsdemoproxy同樣,一樣拖拽一個Http Listener和CXF Component控件。兩個控件配置以下圖所示

Http Listener使用的端口號仍是8081

 

須要指出的是,因爲Asp.net搭建的web service服務器有Soap1.1和Soap1.2兩種協議形式,所以在CXF Proxy Service中必須指定Binding id,即wsdl中的wsdl:binding節點的name屬性,因爲咱們使用Soap1.1協議,所以Binding Id使用1.1協議對應的ServiceSoap1.

啓動webservice1proxy項目,訪問http://localhost:8081/webservice1proxy?wsdl,顯示webservice1的wsdl描述文件。

 

在代理Web Service的wsdl文件成功後,接下來解決第二個問題,即經過Mule ESB轉發Web Service請求到真實的Web Service請求,得到結果返回調用客戶端,咱們經過在Mule ESB項目中使用Web Service Consumer來實現,下文咱們將詳細說明。

2.1 調用CXF 代理Web Service

啓動WsDemo項目,咱們在SoapUI中調用這個Web Service,以下圖所示

 

在WsDemoProxy項目中拖一個Web Service Consumer組件,配置它指向WsDemo的wsdl文件

加載wsdl文件後,Service,Port和Address將自動掃描wsdl文件獲取。

在Operation行的下拉列表中選擇要調用的Web Service方法(這裏只有sayHello方法)

保存後啓動WsDemoProxy項目,再使用SoapUI調用WsDemoProxy代理的Web Service,以下圖所示

和直接調用WsDemo的結果徹底同樣。

使用CXF Client客戶端調用

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

public class WebServiceClientDemo {

	public static void main(String[] args) throws Exception {
		 JaxWsDynamicClientFactory clientFactory = JaxWsDynamicClientFactory.newInstance();
		 
		 Client client = 
				 (Client) clientFactory.createClient("http://localhost:8081/wsdemoproxy?wsdl");
		 		 
	     Object[] result = client.invoke("sayHello","Rick");
	     if(result != null && result.length > 0)
	     {
	    	 System.out.println(result[0].toString());
	     }
	}

}

返回結果以下圖所示

使用.net客戶端進行調用

首先創建一個ServiceReference指向WsDemo Web Service

而後在代碼裏引用生成的代理類HelloServiceImplClient

namespace WebServiceClient
{
    public class Program
    {
        public static void Main(string[] args)
        {
            WsDemoReference.HelloServiceImplClient client = new WsDemoReference.HelloServiceImplClient();
            Console.WriteLine(client.sayHello("Rick"));
        }
    }
}

執行結果以下圖所示(按Ctrl + F5啓動程序,不然Console窗口會一閃而過)

 

2.2 調用Asp.net 代理Web Service

同2.1,咱們修改webservice1proxy項目,因爲WebService1暴露了兩個方法,咱們須要加入兩個Web Service Consumer控件

相關文章
相關標籤/搜索