轉-------------利用AXIS開發Webservice(三) —— 如何傳遞JavaBean和你的對象 (目的:學習)
Posted on 2012-06-07 17:05 小白19870626 閱讀(232) 評論(0) 編輯 收藏 所屬分類: webservice這幾天貌似戰斗力無窮,趁著有精力就多更新兩篇。隨著對Axis的研究加深,越感覺webservice是個很好玩的東西。這篇說一下如何傳遞一個JavaBean和你自己的一個special Object。
在第一篇介紹Axis的文章里,我們做了一個簡單的webservice,我們client side傳遞了String和int類型的數據給service object。Service處理之后返回處理結果給Client。對于大多數需求,那個demo顯然已經足夠應付了。但是如果client端需要傳輸一個對象給server,那么那個demo就顯得力不從心了。Axis中提供了遠程傳輸對象的方法,通過那些方法我們同樣可以隨心的傳遞自己的對象。
我們先從傳遞一個JavaBean開始,首先編寫一個JavaBean。
- package com.chnic.bean;
- public class OrderBean {
- private String name;
- private int age;
- private String[] items;
- private int[] price;
- private boolean checked;
- public OrderBean() {
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public boolean isChecked() {
- return checked;
- }
- public void setChecked(boolean checked) {
- this.checked = checked;
- }
- public String[] getItems() {
- return items;
- }
- public void setItems(String[] items) {
- this.items = items;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int[] getPrice() {
- return price;
- }
- public void setPrice(int[] price) {
- this.price = price;
- }
- }
這個JavaBean的前4個屬性都很清楚,要解釋一下最后一個。因為這個JavaBean被傳遞到Service端處理之后要接著被傳回,用來示例webservce傳進和傳出。這個變量用來區別傳進和傳出的差別。解釋完我們來看下service
- package com.chnic.webservice;
- import com.chnic.bean.OrderBean;
- public class AnalyzeOrder {
- public AnalyzeOrder(){
- }
- public OrderBean process(OrderBean order){
- order.setChecked(true);
- System.out.println("name: " + order.getName() + " age: " + order.getAge());
- for(int i=0; i<order.getItems().length; i++)
- System.out.println("Item " + (i+1) + order.getItems()[i] +
- " and price is " + order.getPrice()[i]);
- return order;
- }
- }
Service Object的代碼很簡單,就不解釋了。慣例,我們來編寫發布文件。
- <deployment xmlns="http://xml.apache.org/axis/wsdd/"
- xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
- <service name="CheckOrder" provider="java:RPC">
- <parameter name="className" value="com.chnic.webservice.AnalyzeOrder"/>
- <parameter name="allowedMethods" value="process"/>
- <beanMapping qname="myNS:Order" xmlns:myNS="urn:AnalyzeOrder"
- languageSpecificType="java:com.chnic.bean.OrderBean"/>
- </service>
- </deployment>
唯一不同的就是多了<beabMapping>這個節點。qname 表示 XML 規范中定義的限定名稱,他由名稱空間 URI、本地部分和前綴組成。除了本地部分其他都不是必須的另外QName是不可變的。xmlns后面的myNS是必須的。具體根據前面所指定的qname來決定。之后可以隨意命名一個namespace。最后的languageSpecificType指定的是你傳遞的對象類型。第一個屬性的本地部分和第二個節點你自定義的命名空間會組成一個新的QName,并將你要傳輸的對象mapping是上去。
發布這個webservice,編寫測試代碼
- String targetEendPoint = "http://localhost:8080/axis/services/CheckOrder";
- OrderBean order = new OrderBean();
- order.setName("Beckham");
- order.setAge(32);
- String [] items = new String[] { "Ipod", "ThinkPad" };
- int [] price = new int [] { 999, 5000 };
- order.setItems(items);
- order.setPrice(price);
- order.setChecked(false);
- System.out.println(order.isChecked());
- Service service = new Service();
- Call call = (Call) service.createCall();
- QName qn = new QName("urn:AnalyzeOrder", "Order" );
- call.registerTypeMapping(OrderBean.class, qn,
- new org.apache.axis.encoding.ser.BeanSerializerFactory(OrderBean.class, qn),
- new org.apache.axis.encoding.ser.BeanDeserializerFactory(OrderBean.class, qn));
- call.setTargetEndpointAddress( new java.net.URL(targetEendPoint) );
- call.setOperationName( new QName("CheckOrder", "process") );
- call.addParameter( "arg1", qn, ParameterMode.IN );
- call.setReturnClass(OrderBean.class);
- OrderBean result = (OrderBean) call.invoke( new Object[] {order} );
- System.out.println("Success...");
- System.out.println(result.isChecked())
從控制臺輸出一些信息以便測試,里面大多代碼都應該見過。new QName和之后的registerTypeMapping方法也是在實現我上面那段黑體字的內容。之后注冊完參數和返回值類型運行。
會發現在tomcat控制臺和本地控制臺都會輸出測試結果,值得注意的是checked這個屬性在傳入之前是false屬性,傳入之后我們改變了他的屬性變為true。返回之后在本地控制臺打印出來也為true。
事實上Axis除了可以傳輸JavaBean之外還可以傳輸一些自定義的類型。比如List、Map和時間日期類型。Axis也為他們提供了專門的SerializerFactory和DeserializerFactory。這些工廠類會產生串行化工具去序列化相應的對象。更多的Factory Object可以在org.apache.axis.encoding.ser下面找到。
對于自定義序列化,Axis也提供了相對性的配置節點。具體配置如下:
- <typeMapping qname="ns:local" xmlns:ns="someNamespace"
- languageSpecificType="java:my.java.thingy"
- serializer="my.java.Serializer"
- deserializer="my.java.DeserializerFactory"
- encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
typeMapping的前三個屬性和上面講的beanMapping都一樣。不一樣的是后三個。serializer指定的是串行化類,dserializer指定的是反串行化類。最后一個指定的編碼方式。其實對于typeMapping來說beanMapping只不過是他的一個簡化版而已。因為beanMapping的串行化和反串行化工廠類都是固定的,而編碼方式也是固定的。
因為typemapping和beanMapping很相似,在這里就不再寫demo了。 有些人也許會問,既然能串行化對象那能不能“串行化”文件呢?這個問題留著下次再說吧。今天米動力了。
小白