Reputation: 2833
During development of an server/client application which uses JAX-WS RPC-style XML, I found that any time I used a LinkedList<T>
as a parameter or return type over JAX-WS, the contents of said LinkedList<T>
would vanish.
I wrote up an example program to demonastrate the issue. In this application, a new Server "Vegeta" is created which can be asked a question by a client "Nappa". Sentences, which are each a LinkedList<Word>
, are passed between them via JAX-WS RPC. These LinkedList<Word>
objects always arrive at the other side empty.
Does anyone know why this happens?
If it helps, my demonstration code is below. Any and all answers will be greatly appreciated.
Interface IServer is the interface used by Nappa to talk to Vegeta:
package com.stuffvegetasays;
import java.util.LinkedList;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style = Style.RPC)
public interface IServer
{
@WebMethod abstract LinkedList<Word> answer(LinkedList<Word> question);
}
Class Vegeta implements IServer (and as such acts as a server) passes itself to Nappa so that Nappa can use RPC to access it's methods
package com.stuffvegetasays;
import java.util.LinkedList;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
@WebService(endpointInterface = "com.stuffvegetasays.IServer")
public class Vegeta implements IServer
{
public static void main(String[] args)
{
Vegeta vegeta = new Vegeta();
System.out.println("Starting Server");
String serverAddress = "http://0.0.0.0:9000/Vegeta";
Endpoint serverEnd = Endpoint.create(vegeta);
serverEnd.publish(serverAddress);
System.out.println("Server Published!");
}
@Override
public LinkedList<Word> answer(LinkedList<Word> question)
{
System.out.println(question);
LinkedList<Word> answer = new LinkedList<Word>();
answer.add(new Word("\n\n"));
answer.add(new Word("It's "));
answer.add(new Word("over "));
answer.add(new Word("NINE "));
answer.add(new Word("THOUSAND!!!"));
return answer;
}
}
Class Nappa acts as the client, making calls to Vegeta's URL.
package com.stuffvegetasays;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class Nappa
{
// Do an RPC style call to the published server "Vegeta".
public static void main(String[] args) {
URL serverURL;
try
{
serverURL = new URL("http://localhost:9000/Vegeta/");
QName appServerQName = new QName("http://stuffvegetasays.com/", "VegetaService");
Service service = Service.create(serverURL, appServerQName);
IServer vegeta = service.getPort(IServer.class);
LinkedList<Word> question = new LinkedList<Word>();
question.add(new Word("Vegeta! "));
question.add(new Word("What "));
question.add(new Word("does "));
question.add(new Word("the "));
question.add(new Word("scouter "));
question.add(new Word("say "));
question.add(new Word("about "));
question.add(new Word("his "));
question.add(new Word("power "));
question.add(new Word("level?"));
System.out.println(question);
LinkedList<Word> quote = vegeta.answer(question);
System.out.println(quote);
}
catch (MalformedURLException e)
{
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
Class Word is just a container for a String with a modified toString() method.
package com.stuffvegetasays;
public class Word
{
String value;
public Word(String value)
{
this.value = value;
}
public String toString()
{
return value;
}
}
Upvotes: 1
Views: 819
Reputation: 42060
Avoid returning collections directly. Instead of returning a
List<X>
, return a JavaBean that has aList<X>
in it. This will give you more detailed control over the marshalling anyway.
Producing a Web Service with JAX-WS and JAXB
See also:
Upvotes: 1