Web Services,用Axis不能傳遞用戶自定義對象。報錯如下:
WARN AttachmentsImpl:558 - Exception:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.io.IOException: No serializer found for class com.box.model.BookDetail in registry org.apache.axis.encoding.TypeMappingDelegate@c68c26c
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.io.IOException: No serializer found for class com.box.model.BookDetail in registry org.apache.axis.encoding.TypeMappingDelegate@c68c26c
at org.apache.axis.encoding.SerializationContext.serializeActual(SerializationContext.java:1507)
at org.apache.axis.encoding.SerializationContext.serialize(SerializationContext.java:980)
at org.apache.axis.encoding.SerializationContext.outputMultiRefs(SerializationContext.java:1055)
at org.apache.axis.message.SOAPBody.outputImpl(SOAPBody.java:145)
at org.apache.axis.message.SOAPEnvelope.outputImpl(SOAPEnvelope.java:478)
at org.apache.axis.message.MessageElement.output(MessageElement.java:1208)
at org.apache.axis.SOAPPart.writeTo(SOAPPart.java:315)
at org.apache.axis.SOAPPart.writeTo(SOAPPart.java:269)
at org.apache.axis.SOAPPart.saveChanges(SOAPPart.java:530)
at org.apache.axis.attachments.AttachmentsImpl.getAttachmentCount(AttachmentsImpl.java:554)
at org.apache.axis.Message.getContentType(Message.java:486)
at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:343)
at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
.....
已解決,下面是關聯代碼:
package com.box.model; import java.util.Date; //訂貨明細 public class BookDetail implements java.io.Serializable { private static final long serialVersionUID = 1L; private Long id; private String ProductCode; // 葯品編碼(醫院) private String ProductName; // 品名 private String ModelName; // 劑型 private String MedicalSpec; // 規格 private String SalerName; // 產地 private String SpecUnit; // 單位 private double Price; // 進價 private int RequestQty; // 請求采購數量 private Date CreateDate; // 創建日期 private String GhsCode; // 供貨商識別號(醫院) private String GHS; // 供貨商名稱 private String StockCode; // 醫院庫房編號 private String Stock; // 醫院庫房名稱 private String Memo; // 備注 private String HisIdentifierCode; // 醫院端記錄唯一標識 private String NbOrderID; // 醫院端記錄唯一標識 private String UUID; //生成get/set }
/** * 根據UUID發送訂單信息,醫葯平台生成訂單ID(唯一識別)返回 * * @param infos * 訂單信息 * @return 成功:返回BookInfo的ID,失敗返回:"ERROR "+原因 * 輸入訂貨Id可以通過getLastBookId獲取,訂貨明細可以通過getBookDetail獲取 */ public String sendBookInfos(String uuid, List<BookDetail> infos) { UUID id = UUID.randomUUID(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String orderID = sdf.format(new Date()) + id.toString(); for (int i = 0; i < infos.size(); i++) { infos.get(i).setNbOrderID(orderID); infos.get(i).setUUID(uuid); } nbJkDAO.insertOrderInfo(infos); return orderID; }
qname="ns:BookDetail" xmlns:ns="urn:BookDetailManager" />
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" /> <service name="NotifyData" provider="java:RPC"> <parameter name="className" value="com.ws.NotifyDataService" /> <parameter name="allowedMethods" value="*" /> </service> // <service name="NbData" provider="java:RPC"> <parameter name="className" value="com.ws.NbDataService" /> <parameter name="allowedMethods" value="*" /> <beanMapping languageSpecificType="java:com.box.model.BookDetail" qname="ns:BookDetail" xmlns:ns="urn:BookDetailManager" /> </service> <transport name="http"> <requestFlow> <handler type="URLMapper" /> </requestFlow> </transport> </deployment>
package com.ws; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; //webService測試 import javax.xml.namespace.QName; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.ser.BeanDeserializerFactory; import org.apache.axis.encoding.ser.BeanSerializerFactory; import com.box.model.BookDetail; public class Test { public static void main(String[] args) { sendRecv(); } public static String sendRecv() { BookDetail bookDetail = new BookDetail(); List<BookDetail> sb = new ArrayList<BookDetail>(); UUID id = UUID.randomUUID(); bookDetail.setNbOrderID("99s"); bookDetail.setUUID(id.toString()); bookDetail.setProductCode("22s"); bookDetail.setProductName("3s"); bookDetail.setModelName("4s"); bookDetail.setMedicalSpec("5s"); bookDetail.setSalerName("6s"); bookDetail.setSpecUnit("7s"); bookDetail.setPrice(8.0); bookDetail.setRequestQty(9); bookDetail.setCreateDate(new Date()); bookDetail.setGhsCode("10s"); bookDetail.setGHS("11s"); bookDetail.setStockCode("12s"); bookDetail.setStock("13s"); bookDetail.setMemo("14s"); bookDetail.setHisIdentifierCode("15s"); sb.add(bookDetail); return sendRecv("123456", sb); } // private static String sendRecv(String arg0, List<BookDetail> sb) { String ret = ""; try { String endPoint = "http://127.0.0.1:8080/ws/services/NbData"; Service service = new Service(); Call call = (Call) service.createCall();
QName qn = new QName("urn:BookDetailManager", "BookDetail"); call.registerTypeMapping(BookDetail.class, qn, new BeanSerializerFactory(BookDetail.class, qn), new BeanDeserializerFactory(BookDetail.class, qn));
call.setTargetEndpointAddress(endPoint); call.setOperationName(new QName("http://main.service.local.wondersgroup.com/", "sendBookInfos")); call.addParameter("arg0", // 參數名 org.apache.axis.encoding.XMLType.XSD_STRING, // 參數類型:String javax.xml.rpc.ParameterMode.IN);// 參數模式:'IN' or 'OUT' call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// 返回值類型:String String result = (String) call.invoke(new Object[] { arg0, sb });// new Object[] { arg0, arg1 } System.out.println("result is :" + result); return result; } catch (Exception e) { e.printStackTrace(); } return ""; } }
關鍵:
QName qn = new QName("urn:BookDetailManager", "BookDetail");
注意service/beanMapping的定義。languageSpecificType中定義使用那個類, qname定義類的名稱。
call.registerTypeMapping(BookDetail.class, qn,
new BeanSerializerFactory(BookDetail.class, qn),
new BeanDeserializerFactory(BookDetail.class, qn));
在Axis客戶端,注冊自定義對象的序列化/反序列化器。
<schema targetNamespace="urn:BookDetailManager" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://model.box.com"/> <import namespace="http://10.18.9.75:8090/ws/services/NbData"/> <import namespace="http://xml.apache.org/xml-soap"/> <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> -<complexType name="BookDetail"> -<sequence> <element name="GHS" type="soapenc:string" nillable="true"/> <element name="UUID" type="soapenc:string" nillable="true"/> <element name="createDate" type="xsd:dateTime" nillable="true"/> <element name="ghsCode" type="soapenc:string" nillable="true"/> <element name="hisIdentifierCode" type="soapenc:string" nillable="true"/> <element name="id" type="soapenc:long" nillable="true"/> <element name="medicalSpec" type="soapenc:string" nillable="true"/> <element name="memo" type="soapenc:string" nillable="true"/> <element name="modelName" type="soapenc:string" nillable="true"/> <element name="nbOrderID" type="soapenc:string" nillable="true"/> <element name="price" type="xsd:double"/> <element name="productCode" type="soapenc:string" nillable="true"/> <element name="productName" type="soapenc:string" nillable="true"/> <element name="requestQty" type="xsd:int"/> <element name="salerName" type="soapenc:string" nillable="true"/> <element name="specUnit" type="soapenc:string" nillable="true"/> <element name="stock" type="soapenc:string" nillable="true"/> <element name="stockCode" type="soapenc:string" nillable="true"/> </sequence> </complexType> </schema>
希望后面的朋友,少走彎路,少掉一些頭發。
