要弄清楚什么是
Holder
類(lèi)型,得先搞清楚
IN
參數(shù),
OUT
參數(shù),
INOUT
參數(shù)的概念。
IN
參數(shù)是
JAVA
因有的參數(shù),
OUT
,
INOUT
參數(shù)不是
JAVA
固有的。
復(fù)制傳遞:IN參數(shù)
java
編程語(yǔ)言對(duì)作為參數(shù)傳遞給方法調(diào)用的所有原始值采用復(fù)制傳遞的方式,即傳遞的值是方法調(diào)用中所使用變量的復(fù)制,而不是原始值本身。比如定義一個(gè)方法
test(int intValue,Date dateValue){
intValue=5;
dateValue=new Date(0);
}
在作如下調(diào)用時(shí)
int intValue=1;
Date dateValue=new Date();
test(intVlaue,dateValue);
System.out.println(intValue) //
打印1
System.out.pritnln(dateValue) //
打印現(xiàn)在的時(shí)間。
但是在
test
方法中對(duì)參數(shù)的值作了修改。而實(shí)際的參數(shù)值并未發(fā)生改變。
引用傳遞
: INOUT
參數(shù)
OUT
參數(shù)
.
在實(shí)現(xiàn)引用傳遞的編程語(yǔ)言中,如果
test
方法的兩面?zhèn)€參數(shù)定義為引用傳遞
,
對(duì)上述
test
方法調(diào)用后,再打印
intValue
跟
dateValue
的值,會(huì)發(fā)現(xiàn)這兩個(gè)值已經(jīng)發(fā)生了改變。但是
OUT
參數(shù)更象一個(gè)返回值,因?yàn)橹狄獜姆椒ㄖ袀鞒龆皇莻魅搿J褂?/span>
OUT
參數(shù)數(shù),激活方法前不訪(fǎng)問(wèn)變量的值,即傳入的值被忽略了。
H
older
類(lèi):
在
JAX-RPC
中支持
INOUT,OUT
參數(shù)。
Holder
是一個(gè)接口,它只是提供了一個(gè)補(bǔ)救措施,以在
java
中支持引用傳遞。這樣就使得需要用
java
與支持
INOUT,OUT
參數(shù)的編程語(yǔ)言寫(xiě)的
web
服務(wù)進(jìn)行通信
.
從
WSDL
映射
HOLDER
類(lèi)型
:
接口定義
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'/><!
—
不要這一行
,
它就是一個(gè)
OUT
參數(shù)
-
à
? <part name='Date_2' type='xsd:dateTime'/>
?</message>
?<message name='HolderTestBeanInterface1_echoCalendarResponse'>
? <part name='Calendar_1' type='xsd:dateTime'/>
?</message> <portType name='HolderTestBeanInterface1'>
? <operation name='echoCalendar' parameterOrder='Calendar_1 Date_2'>
?? <input message='tns:HolderTestBeanInterface1_echoCalendar'/>
?? <output message='tns:HolderTestBeanInterface1_echoCalendarResponse'/>
? </operation>
</portType>
…
?
標(biāo)記為
Calendar_1
的
part
元素既在
input
消息中又在
ouput
消息中
,jax-rpc
編譯器知道它是一個(gè)
INOUT
類(lèi)型
,
同時(shí)也需要
Holer
類(lèi)型。如果在output消息定義一個(gè)part元素,這表示它是一個(gè)返回值或者一個(gè)OUT參數(shù),如果part是一個(gè)OUT參數(shù),part標(biāo)記會(huì)列在operation元素的parameterOrder屬性中.OUT參數(shù)也需要Holder類(lèi)型.
Javax.xml.rpc.holders包中提供了一個(gè)Holder類(lèi),用于映射到j(luò)ava原始類(lèi)型的INOUT參數(shù)和OUT參數(shù)。如IntHolder等,同時(shí)也提供了一組為nillable內(nèi)置類(lèi)型定義的Holder類(lèi)型,如IntegerWrapperHolder等.
自定義Holder類(lèi)型。必須實(shí)現(xiàn)Holder標(biāo)志接口,
其屬性變量名必須為 value 并且必須定義一個(gè)空的構(gòu)造函數(shù)就象下面這樣:
public? class BeanTestHolder implements javax.xml.rpc.holders.Holder {
??? public BeanTest value;
??? public BeanTestHolder(){
?
??? }
?
??? public BeanTestHolder(BeanTest beanTest){
??????? value=beanTest;
??? }
?
}
Jboss
Web Service
的
Holder
類(lèi)型的具體實(shí)現(xiàn)
,
采用
Jboss 4.04
版本
.
定義一個(gè)
bean
類(lèi)
:
public class BeanTest {
??? private String beanName;
??? public BeanTest(){
?
??? }
?
??? public String getBeanName() {
??????? return beanName;
??? }
?
??? public void setBeanName(String beanName) {
??????? this.beanName = beanName;
??? }
?
}
給
bean
定制一個(gè)
Holder:
package holder;
?
public? class BeanTestHolder implements javax.xml.rpc.holders.Holder {
??? public BeanTest value;
??? public BeanTestHolder(){
?
??? }
?
??? public BeanTestHolder(BeanTest beanTest){
??????? value=beanTest;
??? }
?
}
?
?
定義一個(gè)接口
:
public interface HolderTestBeanInterface1 extends Remote {
??? public void echoCalendar(CalendarHolder val, Date date) throws
??????????? RemoteException;
??? public void echoBeanHolder(BeanTestHolder beanTestHolder,BeanTest beanTest) throws
??????????? RemoteException;
}
接口的實(shí)現(xiàn)類(lèi)
:
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</display-name>
??? <servlet-name>HolderTestBeanInterface1</servlet-name>
??? <servlet-class>holder.HolderTestBean</servlet-class>
? </servlet>
? <servlet-mapping>
??? <servlet-name>HolderTestBeanInterface1</servlet-name>
??? <url-pattern>/HolderTestBeanInterface1</url-pattern>
? </servlet-mapping>
? <servlet-mapping>
??? <servlet-name>HolderTestBeanInterface1</servlet-name>
??? <url-pattern>/services/*</url-pattern>
? </servlet-mapping>
打包成
war
文件并發(fā)布
客戶(hù)端的調(diào)用
:
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.. ");
?
?
?
??? }
}
如何調(diào)用
web
服務(wù)參見(jiàn)手記
j2ee web serivce
開(kāi)發(fā)
(
一
)
對(duì)比一下調(diào)用前后的輸出就能明白
Holder
類(lèi)型的作用了
.
完整的示例下載
歡迎加入QQ群