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>
希望后面的朋友,少走弯路,少掉一些头发。