我对网络服务感到生气。
我有一个非常简单的soap webservice:
@Remote
public interface StudentService
{
public String sayHello();
public List<Student> getStudents();
}
并且
@Stateless
@WebService
public class StudentServiceImpl implements StudentService
{
@Override
public String sayHello()
{
return "Hello World";
}
public List<Student> getStudents()
{
List<Student> students = new ArrayList<Student>();
Student st1 = new Student();
st1.setMatricule(1234);
st1.setName("student1");
students.add(st1);
Student st2 = new Student();
st2.setMatricule(5678);
st2.setName("student2");
students.add(st2);
return students;
}
}
和
public class Student implements Serializable
{
private static final long serialVersionUID = 8286393242028201686L;
private int matricule;
private String name;
public int getMatricule()
{
return matricule;
}
public void setMatricule(int matricule)
{
this.matricule = matricule;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
我在glassfish 3.1下部署服务。
使用glassfish控制台,它正在工作。
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getStudentsResponse xmlns:ns2="http://services.tuto.java.com/">
<return>
<matricule>1234</matricule>
<name>student1</name>
</return>
<return>
<matricule>5678</matricule>
<name>student2</name>
</return>
</ns2:getStudentsResponse>
</S:Body>
</S:Envelope>
使用php它也有效(对于这两种方法)。
现在使用java客户端:
import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class Client
{
public static void main(String[] args) throws Exception
{
String endPoint = "http://localhost:8080/StudentServiceImplService/StudentServiceImpl";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endPoint));
call.setOperationName(new QName("http://services.tuto.java.com/","sayHello"));
System.out.println(call.invoke(new Object[0]));
Service service2 = new Service();
Call call2 = (Call) service2.createCall();
call2.setTargetEndpointAddress(new java.net.URL(endPoint));
call2.setOperationName(new QName("http://services.tuto.java.com/","getStudents"));
System.out.println(call2.invoke(new Object[0]));
}
}
第一个电话正在工作但不是第二个电话。
Hello World
12-mars-2012 14:53:23 org.apache.axis.client.Call invoke
GRAVE: Exception:
org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
at org.apache.axis.encoding.ser.SimpleDeserializer.onStartChild(SimpleDeserializer.java:145)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:345)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at Client.main(Client.java:24)
我该怎么办?
经过大量的时间在互联网上搜索并尝试不同的解决方案仍然无效......
有简单的解决方案吗?
感谢。
编辑:
还试过:
public class SoapClient
{
public static void main(String[] args) throws Exception
{
SOAPMappingRegistry smr = new SOAPMappingRegistry();
BeanSerializer beanSer = new BeanSerializer();
smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("http://services.tuto.java.com/", "StudentServiceImplService"),Student.class, beanSer, beanSer);
Call call = new Call();
call.setSOAPMappingRegistry(smr);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
call.setTargetObjectURI("http://services.tuto.java.com/");
call.setMethodName("getStudents");
Response resp;
try
{
resp = call.invoke(new URL("http://8h9l45j:8080/StudentServiceImplService/StudentServiceImpl"), "");
}
catch (SOAPException e)
{
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " + e.getMessage());
return;
}
if (!resp.generatedFault())
{
Parameter ret = resp.getReturnValue();
Object value = ret.getValue();
if ( value != null )
{
String[] tlist = (String[])value;
System.out.println();
for ( int i = 0; i < tlist.length; i++ )
System.out.println(tlist[i]);
}
}
else
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code = "
+ fault.getFaultCode());
System.out.println (" Fault String = "
+ fault.getFaultString());
}
}
结果如下:
Caught SOAPException (SOAP-ENV:Client): No Deserializer found to deserialize a ':return' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.
答案 0 :(得分:3)
使用soap client的第一个响应元素。
问题来自maptypes名称空间:没有名称空间
现在,我有
smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("","student"),Student.class, null, new BeanSerializer());
smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("","matricule"),Integer.class, null, new IntDeserializer());
smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("","name"),Integer.class, null, new StringDeserializer());
并添加
@XmlRootElement(name = "Student",namespace="http://services.tuto.java.com/")
到Student课程
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getStudentsResponse xmlns:ns2="http://services.tuto.java.com/">
<student>
<matricule>1236</matricule>
<name>student1</name>
</student>
<student>
<matricule>5678</matricule>
<name>student2</name>
</student>
</ns2:getStudentsResponse>
</S:Body>
</S:Envelope>
轴客户端:
public class AxisClient
{
public static void main(String[] args) throws Exception
{
String endPoint = "http://localhost:8080/StudentServiceImplService/StudentServiceImpl";
Service service2 = new Service();
Call call2 = (Call) service2.createCall();
call2.setTargetEndpointAddress(new java.net.URL(endPoint));
call2.setOperationName(new QName("http://services.tuto.java.com/","getStudents"));
call2.setReturnType(new QName("","student"), Student.class);
call2.setReturnType(new QName("", "student"));
call2.registerTypeMapping(Student.class, new QName("", "student"), null,new BeanDeserializerFactory(Student.class, new QName("", "student")));
List<Student> students = (List<Student>) call2.invoke(new Object[0]);
for (Student student : students)
{
System.out.println(student);
}
}
}
给予所有学生:
Student [matricule=1236, name=student1]
Student [matricule=5678, name=student2]
axis2客户端:
public static void main(String[] args) throws Exception
{
String endPoint = "http://localhost:8080/StudentServiceImplService/StudentServiceImpl";
ServiceClient sc = new ServiceClient();
Options opts = new Options();
opts.setTo(new EndpointReference("http://localhost:8080/StudentServiceImplService/StudentServiceImpl"));
sc.setOptions(opts);
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://services.tuto.java.com/","ns1");
OMElement method = fac.createOMElement("getStudents", omNs);
OMElement res = sc.sendReceive(method);
System.out.println(res);
Iterator<OMElement> it = res.getChildElements();
while(it.hasNext())
{
System.out.println(it.next());
}
}
给予
<ns2:getStudentsResponse xmlns:ns2="http://services.tuto.java.com/"><student><matricule>1236</matricule><name>student1</name></student><student><matricule>5678</matricule><name>student2</name></student></ns2:getStudentsResponse>
<student><matricule>1236</matricule><name>student1</name></student>
<student><matricule>5678</matricule><name>student2</name></student>
但我不知道如何反序列化这些元素。
我试过
Student student = (Student) BeanUtil.deserialize(Student.class,res,new DefaultObjectSupplier(),null);
但是给了我
Student [matricule=null, name=null]
我该怎么办?
留下问题:
答案 1 :(得分:2)
你能不能使用像
这样的WSDLhttp://localhost:8080/StudentServiceImplService/StudentServiceImpl?wsdl
然后使用轴wsdl2java让Axis为您创建客户端代码(它将具有所有正确的类型映射和命名空间)?
答案 2 :(得分:0)
您使用的SOAP绑定样式是什么, RPC / DOCUMENT ?如果您使用RPC,则将对请求和响应进行编码和处理,Axis2不支持RPC编码格式消息。尝试使用DOCUMENT SOAP绑定样式。 (我应该把它放在评论中,请耐心等待)