web service传递自定义类报No serializer found for class

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)

.....

 

已解决,下面是关联代码:

 

Model类 BookDetail.java:
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
}

 

服务端:
/it3/WEB-INF/src/com/ws/NbDataService.java
 
/**
* 根据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;
}

 

Web Service 配置文件 /it3/WEB-INF/server-config.wsdd
很关键:<beanMapping languageSpecificType="java:com.box.model.BookDetail"
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客户端,注册自定义对象的序列化/反序列化器。 

 
最后附上wsdl部分供参考:
<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>

 

希望后面的朋友,少走弯路,少掉一些头发。

posted @ 2016-09-18 16:08  butcher1874  阅读(9186)  评论(3编辑  收藏  举报