信步漫談之Axis2—基礎介紹


主要介紹如何使用 axis2 開發 webservice 接口。

以下以實例講解如何編寫一個 axis2 的服務端和客戶端。

axis2版本:axis2-1.5.4-bin.zip

目錄結構:

image

關鍵代碼:

package com.alfred.check;

import java.util.Iterator;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;

public class AccessCheck {
	public static void checkUserPwd() throws AxisFault {
		MessageContext msgContext = MessageContext.getCurrentMessageContext();
		// 獲取Head
		Iterator list = (Iterator) msgContext.getEnvelope().getHeader()
				.getFirstElement().getChildren();
		String username = "";
		String password = "";
		while (list.hasNext()) {
			OMElement element = (OMElement) list.next();
			if (element.getLocalName().equals("username")) {
				username = element.getText();
			}
			if (element.getLocalName().equals("password")) {
				password = element.getText();
			}
		}
		if (!username.equals("admin") || !password.equals("123456")) {
			throw new AxisFault(
					" Authentication Fail! Check username/password ");
		}
	}
}
AccessCheck.java
package com.alfred.service;

import org.apache.axis2.AxisFault;

import com.alfred.check.AccessCheck;

public class SoapService {
	public String sayHello(String name) throws AxisFault {
		// 以下是添加axis2訪問頭部驗證
		// AccessCheck.checkUserPwd();
		return "Hello," + name;
	}

	public String getWorld() {
		return "Hello,World";
	}
}
SoapService.java
package com.alfred.client;

import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;

public class ServiceClient {
	public static void main(String args[]) throws AxisFault {
		sendAxis2();
	}

	/**
	 * 添加Header頭部驗證信息
	 *
	 * @return
	 */
	public static OMElement createHeaderOMElement() {
		OMFactory factory = OMAbstractFactory.getOMFactory();
		OMNamespace SecurityElementNamespace = factory.createOMNamespace(
				"http://handler.com", "wsse");
		OMElement authenticationOM = factory.createOMElement("Authentication",
				SecurityElementNamespace);
		OMElement usernameOM = factory.createOMElement("username",
				SecurityElementNamespace);
		OMElement passwordOM = factory.createOMElement("password",
				SecurityElementNamespace);
		usernameOM.setText("admin");
		passwordOM.setText("123456");
		authenticationOM.addChild(usernameOM);
		authenticationOM.addChild(passwordOM);
		return authenticationOM;
	}

	/**
	 * 發送axis2的接口信息
	 * @throws AxisFault
	 */
	private static void sendAxis2() throws AxisFault {
		// 使用RPC方式調用WebService
		RPCServiceClient serviceClient = new RPCServiceClient();

		// 向Soap Header中添加校驗信息
		serviceClient.addHeader(createHeaderOMElement());

		Options options = serviceClient.getOptions();
		// 指定調用WebService的URL
		EndpointReference targetEPR = new EndpointReference(
				"http://127.0.0.1:8080/aw/services/mySoapService");
		options.setTo(targetEPR);
		// 指定sayHello方法的參數值,如果有多個,繼續往后面增加即可
		Object[] opAddEntryArgs = new Object[] { "alfred" };
		// 指定sayHello方法返回值的數據類型的Class對象
		Class[] classes = new Class[] { String.class };
		// 在創建QName對象時,QName類的構造方法的第一個參數表示WSDL,文件的命名空間名,也就是<wsdl:definitions>元素的targetNamespace屬性值
		// 第二個參數是要調用的方法名
		QName opAddEntry = new QName("http://service.alfred.com", "sayHello");
		// 返回參數類型,這個和axis1有點區別
		// invokeBlocking方法有三個參數:
		// 第一個參數的類型是QName對象,表示要調用的方法名;
		// 第二個參數表示要調用的WebService方法的參數值,參數類型為Object[];
		// 第三個參數表示WebService方法的返回值類型的Class對象,參數類型為Class[];
		// 當方法沒有參數時,invokeBlocking方法的第二個參數值不能是null,而要使用new Object[]{}
		// 如果被調用的WebService方法沒有返回值,應使用RPCServiceClient類的invokeRobust方法,
		// 該方法只有兩個參數,它們的含義與invokeBlocking方法的前兩個參數的含義相同
		Object ret = serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs,
				classes)[0];
		System.out.println(ret);
	}

}
ServiceClient.java
<?xml version="1.0" encoding="UTF-8"?>
<serviceGroup>
	<!-- 可以指定發布多個service -->
	<service name="mySoapService">
	    <description>
	        axis2 example
	    </description>
	    <!-- 指定接口類地址 -->
	    <parameter name="ServiceClass">
	        com.alfred.service.SoapService
	    </parameter>
	    <!-- Operation級消息接收器:可以為不同的操作指定不同的消息接收器
	    <operation name="sayHello">
        	<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    	</operation>
	    <operation name="getWorld">
        	<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    	</operation>
	     -->
	    <!-- 服務級消息接收器 -->
	    <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>
</serviceGroup>
services.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!--Axis2 config start-->
	<display-name>Apache-Axis2</display-name>
    <servlet>
        <servlet-name>AxisServlet</servlet-name>
        <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
        <!--<init-param>-->
        <!--<param-name>axis2.xml.path</param-name>-->
        <!--<param-value>/WEB-INF/conf/axis2.xml</param-value>-->
        <!--<param-name>axis2.xml.url</param-name>-->
        <!--<param-value>http://localhost/myrepo/axis2.xml</param-value>-->
        <!--<param-name>axis2.repository.path</param-name>-->
        <!--<param-value>/WEB-INF</param-value>-->
        <!--<param-name>axis2.repository.url</param-name>-->
        <!--<param-value>http://localhost/myrepo</param-value>-->
        <!--</init-param>-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>AxisAdminServlet</servlet-name>
        <servlet-class>
            org.apache.axis2.webapp.AxisAdminServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>AxisServlet</servlet-name>
        <url-pattern>/servlet/AxisServlet</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>AxisServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>AxisServlet</servlet-name>
        <url-pattern>*.jws</url-pattern>
    </servlet-mapping>
	<!--Axis2  end-->

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>
web.xml

在瀏覽器地址欄輸入地址:http://127.0.0.1:8080/aw/services/mySoapService?wsdl(使用tomcat服務器,項目名為aw),可以看到顯示出 webservice 的 wsdl 信息,說明部署成功。

在 ServiceClient 中,調用 sayHello,打印信息:

image

需要注意的一點就是 services.xml 文件的存放位置是固定的:WEB-INF/services/ 任意名字的文件夾 /META-INF/services.xml

Axis2 訪問驗證

axis2 接口可以通過向信息頭部(Header)中添加驗證信息,對接口調用者的身份進行驗證。具體配置步驟是:

1、服務端在想要進行訪問驗證的接口方法中(sayHello),添加驗證模塊(AccessCheck.checkUserPwd());

2、驗證模塊通過獲取 webservice 訪問信息頭部,提取驗證信息,對客戶端傳遞的驗證信息進行進行檢查判斷;

3、客戶端調用接口時,加入訪問驗證信息;

// 向Soap Header中添加校驗信息
serviceClient.addHeader(createHeaderOMElement());

Axis2 的 https 訪問

axis2 如果需要進行 https 訪問,需要加入全局配置文件 axis2.xml (Axis2 下提供了三種配置文件,第一種是整個系統的全局配置 axis2.xml,第二種是服務配置 services.xml,第三種是模塊配置 module.xml),默認該文件是存儲在 /WEB-INF/conf/axis2.xml。axis2.xml 文件可以在 axis2 的開發包下獲取。

在 axis2.xml 中加入一段:

<transportReceiver name="https" class="org.apache.axis2.transport.http.AxisServletListener">
    <parameter name="port">443</parameter>
</transportReceiver>

配置完成后訪問 https://127.0.0.1/aw/services/mySoapService?wsdl 顯示出 webservice 的 wsdl 信息,說明配置成功。

客戶端如果想要訪問 https 的服務端,需將服務端證書加入系統屬性中

//指定服務端證書
System.setProperty("javax.net.ssl.keyStore",ProjConf.SERVER_KEYSTORE);
System.setProperty("javax.net.ssl.keyStorePassword",ProjConf.SERVER_KEYSTORE_PASSWORD);

System.setProperty("javax.net.ssl.trustStore",ProjConf.SERVER_TRUSTSTORE);
System.setProperty("javax.net.ssl.trustStorePassword",ProjConf.SERVER_TRUSTSTORE_PASSWORD);

如果想要手動指定 axis2.xml 文件路徑(例如改為 config 文件夾下),可以在 web.xml 中配置(見上方 web.xml)

<init-param>
        <param-name>axis2.xml.path</param-name>
        <param-value>/WEB-INF/config/axis2.xml</param-value>
</init-param>

常見錯誤

1、javax.servlet.ServletException: org.apache.axis2.AxisFault: The system is attempting to engage a module that is not available: addressing

解決方法:到 axis2.xml 中查找

<!-- Comment this to disable Addressing -->
<module ref="addressing"/>

將 addressing 的引用注釋掉。

2、https is forbidden

解決方法:核實 axis2.xml 文件位置是否正確,默認是在 WEB-INF/conf/axis2.xml,以及 axis2.xml 中是否配置了 https。

3、unable to find valid certification path to requested target

解決方法:核實客戶端訪問 https 是否將證書加入系統屬性。

最后,項目的結構如下:

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM