J2EE web service開發(fā)(六)Web服務通信Holder類型
要弄清楚什么是 Holder 類型,得先搞清楚 IN 參數, OUT 參數, INOUT 參數的概念。
IN 參數是 JAVA 因有的參數, OUT , INOUT 參數不是 JAVA 固有的。
復制傳遞:IN參數
java 編程語言對作為參數傳遞給方法調用的所有原始值采用復制傳遞的方式,即傳遞的值是方法調用中所使用變量的復制,而不是原始值本身。比如定義一個方法
- test(int intValue,Date dateValue){
- intValue=5;
- dateValue=new Date(0);
- }
在作如下調用時
- int intValue=1;
- Date dateValue=new Date();
- test(intVlaue,dateValue);
- System.out.println(intValue) // 打印1
- System.out.pritnln(dateValue) // 打印現在的時間。
但是在 test 方法中對參數的值作了修改。而實際的參數值并未發(fā)生改變。
引用傳遞 : INOUT 參數 OUT 參數 .
在實現引用傳遞的編程語言中,如果 test 方法的兩面?zhèn)€參數定義為引用傳遞 , 對上述 test 方法調用后,再打印 intValue 跟 dateValue 的值,會發(fā)現這兩個值已經發(fā)生了改變。但是 OUT 參數更象一個返回值,因為值要從方法中傳出而不是傳入。使用 OUT 參數數,激活方法前不訪問變量的值,即傳入的值被忽略了。
Holder 類:
在 JAX-RPC 中支持 INOUT,OUT 參數。 Holder 是一個接口,它只是提供了一個補救措施,以在 java 中支持引用傳遞。這樣就使得需要用 java 與支持 INOUT,OUT 參數的編程語言寫的 web 服務進行通信 .
從 WSDL 映射 HOLDER 類型 :
接口定義
- public interface HolderTestBeanInterface1 extends Remote {
- public void echoCalendar(CalendarHolder val, Date date) throws
- RemoteException;
- public void echoBeanHolder(BeanTestHolder beanTestHolder,BeanTest beanTest) throws
- RemoteException;
- }
WSDL 文檔
- < ?xml version="1.0" encoding="UTF-8"?>
- < definitions name='HolderTestBeanInterface1' targetNamespace='http://holder' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://holder' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
- < message name='HolderTestBeanInterface1_echoCalendar'>
- < part name='Calendar_1' type='xsd:dateTime'/>
- < part name='Date_2' type='xsd:dateTime'/>
- < /message>
- < message name='HolderTestBeanInterface1_echoCalendarResponse'>
- < part name='Calendar_1' type='xsd:dateTime'/>
- < /message>
- < operation name='echoCalendar' parameterOrder='Calendar_1 Date_2'>
- < input message='tns:HolderTestBeanInterface1_echoCalendar'/>
- < output message='tns:HolderTestBeanInterface1_echoCalendarResponse'/>
- < /operation>
- < /portType>
- …
標記為 Calendar_1 的 part 元素既在 input 消息中又在 ouput 消息中 ,jax-rpc 編譯器知道它是一個 INOUT 類型 , 同時也需要 Holer 類型。如果在output消息定義一個part元素,這表示它是一個返回值或者一個OUT參數,如果part是一個OUT參數,part標記會列在operation元素的parameterOrder屬性中.OUT參數也需要Holder類型.
Javax.xml.rpc.holders包中提供了一個Holder類,用于映射到java原始類型的INOUT參數和OUT參數。如IntHolder等,同時也提供了一組為nillable內置類型定義的Holder類型,如IntegerWrapperHolder等.
自定義Holder類型。必須實現Holder標志接口, 其屬性變量名必須為 value 并且必須定義一個空的構造函數就象下面這樣:
- public class BeanTestHolder implements javax.xml.rpc.holders.Holder {
- public BeanTest value;
- public BeanTestHolder(){
- }
- public BeanTestHolder(BeanTest beanTest){
- value=beanTest;
- }
- }
Jboss Web Service 的 Holder 類型的具體實現 , 采用 Jboss 4.04 版本 .
定義一個 bean 類 :
- public class BeanTest {
- private String beanName;
- public BeanTest(){
- }
- public String getBeanName() {
- return beanName;
- }
- public void setBeanName(String beanName) {
- this.beanName = beanName;
- }
- }
給 bean 定制一個 Holder:
- package holder;
- public class BeanTestHolder implements javax.xml.rpc.holders.Holder {
- public BeanTest value;
- public BeanTestHolder(){
- }
- public BeanTestHolder(BeanTest beanTest){
- value=beanTest;
- }
- }
定義一個接口 :
- public interface HolderTestBeanInterface1 extends Remote {
- public void echoCalendar(CalendarHolder val, Date date) throws
- RemoteException;
- public void echoBeanHolder(BeanTestHolder beanTestHolder,BeanTest beanTest) throws
- RemoteException;
- }
接口的實現類 :
- import javax.xml.rpc.holders.*;
- import java.util.Date;
- public class HolderTestBean implements HolderTestBeanInterface1 {
- public void echoCalendar(CalendarHolder val,Date date) {
- System.out.println("echoCalendar: " + val.value.getTime());
- val.value.setTime(new Date());
- System.out.println(date);
- }
- public void echoBeanHolder(BeanTestHolder beanTestHolder,BeanTest beanTest){
- BeanTest beantest=beanTestHolder.value;
- System.out.println(beantest.getBeanName()+ " holder ");
- beantest.setBeanName(" new name ");
- System.out.println(beantest.getBeanName()+ " holder ");
- System.out.println(beanTest.getBeanName()+ " bean ");
- beanTest.setBeanName(" new name too ");
- System.out.println(beanTest.getBeanName()+" bean ");
- }
- }
用于 jboss 自帶的 wstools 工具的配置文件 wstools-config.xml
- < ?xml version="1.0" encoding="UTF-8"?>
- < !--
- wstools -cp classes -config wstools-config.xml
- -->
- < configuration xmlns="http://www.jboss.org/jbossws-tools"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.jboss.org/jbossws-tools http://www.jboss.org/jbossws-tools/schema/jbossws-tool_1_0.xsd">
- < java-wsdl>
- < service name="HolderTestBeanInterface1" style="rpc" endpoint="holder.HolderTestBeanInterface1"/>
- < namespaces target-namespace="http://holder" type-namespace="http://holder"/>
- < mapping file="HolderTestBeanInterface1.xml"/>
- < webservices servlet-link="HolderTestBeanInterface1"/>
- < /java-wsdl>
- < /configuration>
生成所需的 webservices.xml,jax-rpc 映射文件 , 及 wsdl 文檔
wstools -config wstools-config.xml
把生成的 wsdl 文件夾 ,webservices.xml 及映射文件放到 web-inf 目錄下。
配置 web.xml 文件
- < servlet>
- < display-name>HolderTestBeanInterface1 Servlet
- < servlet-name>HolderTestBeanInterface1
- < servlet-class>holder.HolderTestBean
- < /servlet>
- < servlet-mapping>
- < servlet-name>HolderTestBeanInterface1
- < url-pattern>/HolderTestBeanInterface1
- < /servlet-mapping>
- < servlet-mapping>
- < servlet-name>HolderTestBeanInterface1
- < url-pattern>/services/*
- < /servlet-mapping>
打包成 war 文件并發(fā)布
客戶端的調用 :
- import java.net.URL;
- import javax.xml.rpc.*;
- import javax.xml.namespace.QName;
- import java.util.*;
- import java.io.File;
- import javax.xml.rpc.holders.CalendarHolder;
- import org.jboss.ws.jaxrpc.ServiceFactoryImpl;
- public class ClientTest {
- private HolderTestBeanInterface1 getPort() throws Exception {
- ServiceFactoryImpl factory = new ServiceFactoryImpl();
- URL wsdlURL = new File(
- "holderTest/WEB-INF/wsdl/HolderTestBeanInterface1.wsdl").toURL();
- URL mappingURL = new File(
- "holderTest/WEB-INF/HolderTestBeanInterface1.xml").toURL();
- QName qname = new QName("http://holder", "HolderTestBeanInterface1");
- Service service = factory.createService(wsdlURL, qname, mappingURL);
- HolderTestBeanInterface1 port = (HolderTestBeanInterface1) service.getPort(HolderTestBeanInterface1.class);
- return port;
- }
- public static void main(String[] args) throws Exception{
- ClientTest clienttest = new ClientTest();
- HolderTestBeanInterface1 h=clienttest.getPort();
- Date date=new Date();
- System.out.println(date+ " date begin... ");
- GregorianCalendar value = new GregorianCalendar(2006, 1, 1, 23, 59, 59);
- CalendarHolder holder = new CalendarHolder(value);
- System.out.println(holder.value.getTime()+" calendarHolder begin... ");
- h.echoCalendar(holder,date);
- System.out.println(holder.value.getTime()+" calendarHolder end ... ");
- System.out.println(date+ " date end ... ");
- BeanTest beanTest=new BeanTest();
- beanTest.setBeanName("test");
- BeanTest beanTest2=new BeanTest();
- beanTest2.setBeanName("test2");
- System.out.println(beanTest.getBeanName()+" holder begin.. ");
- System.out.println(beanTest2.getBeanName()+" bean begin..");
- BeanTestHolder beanTestHolder = new BeanTestHolder(beanTest);
- h.echoBeanHolder(beanTestHolder,beanTest2);
- System.out.println(beanTest2.getBeanName() + " bean end..");
- System.out.println(beanTestHolder.value.getBeanName()+" holder end.. ");
- }
- }
這樣,J2EE web Service開發(fā)中的Web服務通信Holder類型就介紹完了。
【編輯推薦】