1. 程式人生 > >webservice服務端釋出與呼叫 JAX-WS cxf axis2

webservice服務端釋出與呼叫 JAX-WS cxf axis2

之前專案中需要用到webservice的釋出最後做出了幾個例子如下:

1 基礎 JAX-WS例項

介面釋出:
package com.test;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;

/** 
 *  @WebService - 它是一個註解,用在類上指定將此類釋出成一個ws. 
    Endpoint – 此類為端點服務類,它的方法publish用於將一個已經添加了@WebService註解物件繫結到一個地址的埠上。 
  
 * 
 */ 
@WebService(targetNamespace="http://DemoTest/com/")
public class DemoTest {
	
@WebMethod(operationName="sayHelloMyName")//修改暴露的方法名 public String sayHello(String name){ return "hello "+name; } /** *新增exclude=true後,sayBye()方法不會被髮布 * @param name * @return */ @WebMethod(exclude=true) public String sayBye(String name){ return "bye "+name; } public static void main(String[] args) { Endpoint.publish("http://localhost:456/helloWord",new DemoTest()); System.out.println("webservice start..."); //訪問http://localhost:456/helloWord?wsdl } }
以上這種方法是通過java中自帶的包的一種釋出方式 執行main方法:
然後通過 wsimpost命令生成客戶端程式碼:

wsimpost命令有幾個重要的引數:

    -keep:是否生成java原始檔
    -d:指定輸出目錄
    -s:指定原始碼輸出目錄
    -p:以package的形式生成檔案
    -verbose:在控制檯顯示輸出資訊


wsimport -keep -s D: -p com.client http://localhost:456/helloWord?wsdl
就會在D盤的com資料夾下的client資料夾下生成客戶端 然後自己移到工作空間就好了。
這裡注意的是:上面命令列中標紅的地方 -p com.client其實是在包com中的client包中移到eclipse的時候也要是這個路徑 否則需要改生成的客戶端的一些程式碼
測試類的程式碼如下:
package com.client;

public class MainRun {
	public static void main(String[] args) {
			DemoTestService dws=new DemoTestService();
			DemoTest a=dws.getDemoTestPort();
			String result=a.sayHelloMyName("張三");
			System.out.println(result);
	}

}


2.cxf    webservice  例項

這裡只是cxf基於spring 的釋出方式其實個人感覺和JAX-WS釋出方式差不多 介面:
package com.test;

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

@WebService
public interface DemoTest2 {
	@WebMethod
	public String sayHello(@WebParam(name="param")String param);
}

實現類:
package com.test;

public class DemoTest2Impl implements DemoTest2 {

	@Override
	public String sayHello(String param) {
		
		return "hello "+param;
	}

}
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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>abc</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!-- cxf服務啟動servlet -->
    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/webService/*</url-pattern>
    </servlet-mapping>
</web-app>
applicationContext.xml
<?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:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://cxf.apache.org/jaxws
      http://cxf.apache.org/schemas/jaxws.xsd">

	<!-- 兩種釋出方式 -->
	<!-- 第一種 -->
	<jaxws:endpoint id="DemoTest2" implementor="com.test.DemoTest2Impl" address="/DemoTest2" />	
		<!-- 第二種 -->
	<bean id="serviceTest" class="com.test.DemoTest2Impl"></bean>
	<jaxws:server address="/test2" serviceClass="com.test.DemoTest2">
		<jaxws:serviceBean>
			<ref bean="serviceTest" />
		</jaxws:serviceBean>
	</jaxws:server>


</beans>

這是一個介面釋出了兩次訪問地址分別為:
http://localhost:8080/WebServiceDemo2/webService/DemoTest2?wsdl http://localhost:8080/WebServiceDemo2/webService/test2?wsdl
注意:jar包需要引對 
地址拼寫為: 地址:埠/專案名/web.xml中的CXFServlet自定義的對映的名字/spring配置中的地址?wsdl
客戶端呼叫按照第一種方式用wsimport生成客戶端進行呼叫

3.axis2 werbservice 例項(我在用axis2釋出的時候出現過好多問題,最終雖然解決了但是他的底層還是不太清晰,不足之處請大神指點一二)

axis2釋出有多重方式  這裡只具體針對一種方式進行舉例 如果看其他的方式可以訪問http://blog.csdn.net/qq877507054/article/details/61922139
首先在http://axis.apache.org/axis2/java/core/download.cgi下載axis2的war解壓縮後將 conf modules和services 複製到專案 WEB-INF 下如下

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>WebServiceDemo</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <servlet>      
    <servlet-name>AxisServlet</servlet-name>      
    <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>      
    <load-on-startup>1</load-on-startup>      
</servlet>           
<servlet-mapping>      
           <servlet-name>AxisServlet</servlet-name>      
           <url-pattern>/webService/*</url-pattern>      
</servlet-mapping>
</web-app>
請看上面xml中的這句話<url-pattern>/ webService/*</url-pattern> 和cxf的webservice中的web.xml中那句話起的作用一樣  是為了攔截webservice的請求。 但是axis2釋出webservice的時候他有個檔案是axis2.xml 他預設攔截貌似是/services/的      所以如果你web.xml中用的是<url-pattern>/webService/*</url-pattern> 這個的話你需要修改axis2.xml中的一句話<parameter name="servicePath">services</parameter>如果是註釋的就放開    改成和web.xml中一樣的攔截  改成:<parameter name="servicePath"> webService </parameter>    如果兩邊不一致的話即使wsdl可以訪問  客戶端呼叫也會報錯 錯誤是:the service cannot be found for the endpoint reference (EPR) ...
services.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- service的name是暴露的服務介面 -->
<service name="DemoTest3" targetNamespace="http://DemoTest3/com/">
	<!-- 設定名稱空間 -->
	<schema schemaNamespace="http://DemoTest3/com/"/>
	<!-- 類路徑 -->
	<parameter name="ServiceClass">com.test.DemoTest3</parameter>
	<!-- 訊息接收器 -->
	<messageReceivers>
		<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
			class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
		<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
			class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
	</messageReceivers>
</service>  
上面service.xml中的標紅的兩端最好一致


介面類:
package com.test;

public class DemoTest3 {

	public String sayHello(String name){
		
		return "hello "+name;
	}
}

訪問路徑為:http://localhost:8080/WebServiceDemo3/webService/DemoTest3?wsdl
客戶端呼叫: 這次使用rpc的方式呼叫介面
程式碼:
package com.test;

import javax.xml.namespace.QName;

import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class MainRun {

	public static void main(String[] args) throws Exception {
		 // 使用RPC方式呼叫WebService
		 RPCServiceClient serviceClient = new RPCServiceClient();
		 Options options = serviceClient.getOptions();
		 // 指定呼叫WebService的URL
		 EndpointReference targetEPR = new EndpointReference("http://localhost:8080/WebServiceDemo3/webService/DemoTest3?wsdl");
		 options.setTo(targetEPR);
		 // 指定方法的引數值
		 String parameter = "張三";
		 Object[] opArgs = new Object[] { parameter };
		 // 指定方法返回值的資料型別的Class物件
		 Class[] opReturnType = new Class[] { String.class };
		 // 指定要呼叫的方法及WSDL檔案的名稱空間
		 QName opQName = new QName("http://DemoTest3/com/","sayHello");
		 // 呼叫方法輸出返回值
		 Object[] result = null;
		 result = serviceClient.invokeBlocking(opQName, opArgs, opReturnType);
		 System.out.println((String)result[0]);
	}
}

呼叫結果如下:


注意:如果你呼叫的時候報錯:The ServiceClass object does not implement the required method in the following form: OMElement。。。 則需要將你的service.xml中的 http://www.w3.org/2004/08/wsdl/in-out和http://www.w3.org/2004/08/wsdl/in-only 改成
http://www.w3.org/ns/wsdl/in-out和http://www.w3.org/ns/wsdl/in-only  就ok了應該

至於為什麼  我在網上搜說是版本問題咋著呢 具體我也沒研究。
關於rpc有比我更詳細的:http://blog.csdn.net/csh624366188/article/details/8362696