调用soap webservice从带有轴的java客户端返回对象列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9668583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Invoke soap webservice returning list of objects from java client with axis
提问by tweetysat
I'm getting mad with webservices.
我对网络服务很生气。
I have a very simple soap webservice :
我有一个非常简单的肥皂网络服务:
@Remote
public interface StudentService
{
public String sayHello();
public List<Student> getStudents();
}
And
和
@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;
}
}
And
和
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;
}
}
I deploy the service under glassfish 3.1.
我在 glassfish 3.1 下部署服务。
Using the glassfish console, it's working.
使用 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>
Using php it's also working (for both methods).
使用 php 它也可以工作(对于这两种方法)。
Now with a java client :
现在有了一个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]));
}
}
The first call is working but not the second one.
第一个调用有效,但第二个调用无效。
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)
What can I do ?
我能做什么 ?
After lot of hours searching on internet and trying differents solutions still nothing working ...
在互联网上搜索了很多小时并尝试了不同的解决方案后,仍然没有任何效果......
Is there a simple solution ?
有简单的解决方案吗?
Thanks.
谢谢。
Edit :
编辑 :
Also tried that :
也试过:
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());
}
}
With that result :
结果是:
Caught SOAPException (SOAP-ENV:Client): No Deserializer found to deserialize a ':return' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.
采纳答案by tweetysat
First element of response using soap client.
使用soap客户端响应的第一个元素。
The problem is coming from the maptypes name space : there is no namespace
问题来自 maptypes 命名空间:没有命名空间
So now, I have
所以现在,我有
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());
And also add
并且还添加
@XmlRootElement(name = "Student",namespace="http://services.tuto.java.com/")
to the Student class to have
到学生类有
<?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>
The axis client :
轴客户端:
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);
}
}
}
Giving allstudents :
给所有学生:
Student [matricule=1236, name=student1]
Student [matricule=5678, name=student2]
The axis2 client :
轴 2 客户端:
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());
}
}
Giving
给予
<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>
But I don't know how to deserialize the omelement.
但我不知道如何反序列化omelement。
I tried with
我试过
Student student = (Student) BeanUtil.deserialize(Student.class,res,new DefaultObjectSupplier(),null);
but gives me
但给了我
Student [matricule=null, name=null]
How can I do ?
我能怎么做 ?
Leaving problems :
留下问题:
- don't know how to do the same with axis --OK See before--/axis 2
- the 'resp' (soap client) contains only firststudent
- 不知道如何对轴做同样的事情--OK 见前--/轴 2
- “resp”(肥皂客户端)仅包含第一个学生
回答by Murugesh
Whats the SOAP binding style you are using,RPC/DOCUMENT? If you are using RPC then the request and response will be encoded and processed,Axis2 is not supporting the RPC encoded format messages. Try using DOCUMENT SOAP binding style. (I should have put this in comments,kindly bear)
您使用的 SOAP 绑定样式是什么,RPC/DOCUMENT?如果您使用 RPC,那么请求和响应将被编码和处理,Axis2 不支持 RPC 编码格式的消息。尝试使用 DOCUMENT SOAP 绑定样式。(我应该把这个放在评论中,请忍耐)
回答by beny23
Can you not get to the WSDL something like
你不能进入 WSDL 之类的吗
http://localhost:8080/StudentServiceImplService/StudentServiceImpl?wsdl
and then use axis wsdl2javato let Axis create the client code for you (which will have all the correct type mappings and namespaces)?
然后使用axis wsdl2java来让Axis 为您创建客户端代码(它将具有所有正确的类型映射和命名空间)?