On Wednesday 09 January 2008, Xavier Luiz wrote:
> I'm not sure if this has been resolved or what the answer is on this
> but the 2.0.4 incubator snapshot WSDL2Java and Java2WSDL tools are not
> creating the return types that our application needs. Here's the
> underlying issue...
>
> Is it possible to return a custom object array instead of a
> java.util.List?
Hmm... The answer seems to be no, but this is per spec. I THOUGHT a
jaxb customization might work (<jxb:globalBindings
collectionType="indexed"/>) and that does make any of the collections in
the types (like any collection in the StockQuote object) be changed from
a List to an array. However, that has no impact on the jaxws generated
stuff (port type interface). I checked the RI and it generates the
same as CXF. I also checked the JAX-WS spec and that doesn't make any
allowance for making that an array. The parts generated on the
interface need to be the collections.
I guess my suggestion would be to not bother running wsdl2java at all.
Use the same interface/objects on the client side as you do on the
server side. Move the StockQuoteService interface and all the types it
needs into a shared jar.
Note: the RequestWrapper and ResponseWrapper annotations are wrong. They
should point to classes that would implement the wrapper types. Like a
GetQuotes.java. My suggestion is to just eliminate those
annotations. For CXF, they aren't needed at all.
Dan
> Here's the example class I have that returns a collection of objects.
> With everything I've read and tried it looks like the CXF Java2WSDL
> and WSDL2Java classes doesn't build a wsdl with the correct element
> and sequence tree in order for the WSDL2Java to build the correct
> service stub. Any help is greatly appreciated.
>
>
> Here's my class examples...
>
>
> Interface class:
> package com.cifrato.external.ws;
>
>
> import com.cifrato.data.wrapper.StockQuote;
>
>
> import javax.jws.WebService;
> import javax.jws.WebParam;
> import javax.jws.WebResult;
> import javax.jws.WebMethod;
> import javax.xml.ws.RequestWrapper;
> import javax.xml.ws.ResponseWrapper;
> import javax.jws.soap.SOAPBinding;
> import javax.jws.soap.SOAPBinding.Style;
> import javax.jws.soap.SOAPBinding.Use;>
>
>
> @SOAPBinding(style=Style.DOCUMENT,use=Use.LITERAL)
> @WebService(name="StockQuoteServicePortType")
> public interface StockQuoteService {
> @RequestWrapper(className="java.lang.String")
>
> @ResponseWrapper(className="com.cifrato.data.wrapper.StockQuote")
> @WebResult(name="StockQuote")
> @WebMethod(operationName="getQuotes",exclude=false)
> public StockQuote[] getQuotes(@WebParam(name = "symbols")
> String[] symbols);
>
> }
>
>
>
>
>
> Implementation class:
> package com.cifrato.external.ws;
>
>
>
> import com.cifrato.data.wrapper.StockQuote;
>
> public class StockQuoteServiceImpl implements StockQuoteService {
>
>
>
> public StockQuote[] getQuotes(String[] symbols) {
> StockQuote[] quotes = null;
> if (symbols != null && symbols.length != 0) {
> quotes = new
> StockQuote[symbols.length];
> for (int i = 0; i <
> symbols.length; i++) {
>
> quotes[i].setSymbol(symbols[i]);
> quotes[i].setPrice(i +
> 1 * 5);
> }
> } else {
> quotes = new StockQuote[2];
> quotes[0].setSymbol("IBM");
> quotes[0].setPrice(50);
> quotes[1].setSymbol("MSFT");
> quotes[1].setPrice(100);
> }
>
> return quotes;
> }
>
> }
>
>
>
>
>
> Custom object class to return as a collection:
> package com.cifrato.data.wrapper;
>
>
>
> public class StockQuote {
>
>
> private String symbol;
> private int price;
> public String getSymbol() {
> return symbol;
>
> }
>
> public void setSymbol(String symbol) {
> this.symbol = symbol;
>
> }
>
> public int getPrice() {
> return price;
>
> }
>
> public void setPrice(int price) {
> this.price = price;
>
> }
>
>
>
> }
>
>
>
> Build.xml:
> <?xml version="1.0"?>
> <project name="cxf-test" basedir=".">
>
> <property environment="system" />
> <property name="host.name" value="localhost" />
> <property name="java.home" value="${system.JAVA_HOME}"/>
> <property name="jetty.home" value="${system.JETTY_HOME}"
> /> <property name="hamachi.home"
> value="${system.JETTY_HOME}/hamachi" />
>
> <echo message="${os.name}"/>
>
>
>
> <path id="cxf.classpath">
> <fileset dir="lib">
> <include name="*.jar"/>
> </fileset>
>
> </path>
>
>
>
> <!--
> ================================================================== -->
>
> <!-- GENERATE WSDL FROM WEB SERVICE CLASSES FROM SERVER
> PACKAGE -->
>
> <!--
> ================================================================== -->
>
> <target name="test.wsdl" depends="server"
> description="GENERATE WSDL">
> <delete file="test.wsdl" quiet="true"/>
> <delete dir="build/wsdl" quiet="true"/>
> <mkdir dir="build/wsdl"/>
> <java
> classname="org.apache.cxf.tools.java2wsdl.JavaToWSDL" fork="true">
> <classpath refid="cxf.classpath"/>
> <arg value="-cp"/>
> <arg
> value="lib/cifrato_server.jar"/>
> <arg value="-o"/>
> <arg value="test.wsdl"/>
> <arg value="-d"/>
> <arg value="build/wsdl"/>
> <arg value="-quiet"/>
> <arg
> value="com.cifrato.external.ws.StockQuoteService"/>
> </java>
> </target>
>
>
>
> <!--
> ================================================================== -->
>
> <!-- GENERATE JAVA FROM WSDL wsdl2java -d build/classes
> -compile ./wsdl/hello_world.wsdl -->
>
> <!--
> ================================================================== -->
> <target name="test.stub">
> <copy file="build/wsdl/test.wsdl"
> todir="${basedir}" overwrite="true" />
> <delete
> dir="src/java/client/com/cifrato/client/external/cxf/ws"
> quiet="true"/> <mkdir
> dir="src/java/client/com/cifrato/client/external/cxf/ws"/>
> <java
> classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
> <classpath refid="cxf.classpath"/>
> <arg value="-client" />
> <arg value="-p" />
> <arg
> value="com.cifrato.client.external.cxf.ws"/>
> <arg value="-d" />
> <arg value="src/java/client" />
> <arg value="${basedir}/test.wsdl"
> /> </java>
> </target>
>
> </project>
--
J. Daniel Kulp
Principal Engineer, IONA
[EMAIL PROTECTED]
http://www.dankulp.com/blog