You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Luc Dewavrin <lu...@gmail.com> on 2010/09/28 15:38:33 UTC

@ResponseWrapper usage

Hi,

i wanted to control the WSDL from a JAXWS webservice endpoint and used a
ResponseWrapper in order to do that.
I didn't like the generated WSDL since it used a wrapping "return" element
for the type of the wsdl:part for the response
and wanted to get rid of it.
The response element looked like this:
<response>
   <return>
      <message></message>
    </return>
</reponse>

All i want is a more "direct" type for the reponse without the <return>
element.
I thought about using a ResponseWrapper and created one:

@ResponseWrapper(className="test.ResponseWrapper")
Response generateResponse()

The generated WSDL looks fine since the type defined in the ResponseWrapper
is used directly (no more
wrapping element).

Here's the content of the ReponseWrapper:
package test;

@XmlRootElement
@XmlType(propOrder = {"message"})
@XmlAccessorType(XmlAccessType.FIELD)
public class ResponseWrapper {
     @XmlElement(name="message")
    private String message;
    public String getMessage() {
         return message;
    }

   public void setMessage(String aMessage) {
       message=aMessage;
   }

   public void setResponse(Response response) {
           this.message=response.getMessage();
   }

  public Response getResponse() {
        return new Response(message);
  }

}

But when i invoke the webservice i never see the <message> element. The
field does not appear in the response.
Maybe i don't understand the usage of the ResponseWrapper and haven't found
much information on it .
I added a breakpoint in the setResponse method but it's never reached.

Thanks in advance,
Luc

Re: @ResponseWrapper usage

Posted by Daniel Kulp <dk...@apache.org>.

On Thursday 30 September 2010 9:55:56 pm Luc Dewavrin wrote:
> Ok thanks for the reply.
> 
> Actually my Response object does not have only 1 field, it has more (i
> simplified my example)
> so 2) and 3) won't work.
> 
> For 1) yes it would work but actually i don't understand why by default 2
> wrapping elements
> are created for the response object (in Wrapped mode).  


Per spec, when in wrapped mode,  whatever you return from the method is not 
considered a wrapper, it's data that is then wrapped with an element based on 
the operation name.   "response" element is from the wrapper that is generated 
and the "return" represents the Response object that is returned.  That is 
completely per spec.

If you want that gone, you have three options:
1) Switch to BARE

2) Only return "field1" as a return, and user Holders as additional method 
parms for the other fields:

@WebResult(name = "field1")
String doFoo(...,  
       @WebParam(name = "field2", mode = OUT) Holder<String> field2) {
...
}

3) I haven't tried this at all, but you could try investigating this.  If you 
switch from Sun's JAXB implementation to the Eclipse MOXY based 
implementation, they have additional annotations to control where/how things 
are outputted.   See:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html



Dan



> As i said, for the
> response object i get
> the following structure :
> <reponse xmlns="urn:mynamespace">
>    <return>
>      <field1>field1Value</field1>
>       <field2>field2Value</field2>
>    </return>
> </response>
> 
> With a Response class like the following one :
> @XmlAccessorType(AccessType.FIELD)
> public class Response {
>    private String field1;
>    private String field2;
> }
> 
> and the wsdl:part is the following :
>   <wsdl:message name="Response">
>     <wsdl:part element="tns:response" name="parameters">
>     </wsdl:part>
>   </wsdl:message>
> referring to these types:
>   <xsd:element name="response" type="tns:Response"></xsd:element>
>   <xsd:complexType name="Response">
>     <xsd:sequence>
>       <xsd:element minOccurs="0" name="return"
> type="ns0:Response"></xsd:element>
>     </xsd:sequence>
>   </xsd:complexType>
> 
> I wanted to get rid of the <return> element which i found useless using my
> own Response wrapper but
> i didn't manage to accomplish it. The generated WSDL looked fine but at
> runtime my fields do not appear
> in the response element when the method is invoked. I guess i'll have to
> switch to BARE mode to make it work.
> 
> Luc
> 
> On Tue, Sep 28, 2010 at 4:16 PM, Daniel Kulp <dk...@apache.org> wrote:
> > A few thoughts:
> > 
> > 1) You may just want to switch to BARE mode where you would have complete
> > control over the JAXB objects used to form the request/response.
> > 
> > 2) Why not just return a String from the method?
> > @WebReturn(name="message")
> > String generateResponse(..);
> > 
> > 3) You MAY be able to do this with the wrapper like:
> > @XmlElement(name="message")
> > Response response
> > 
> > and then adding an @XmlValue to the message thing in the Reponse.  Not
> > really
> > sure though.
> > 
> > Dan
> > 
> > On Tuesday 28 September 2010 9:38:33 am Luc Dewavrin wrote:
> > > Hi,
> > > 
> > > i wanted to control the WSDL from a JAXWS webservice endpoint and used
> > > a ResponseWrapper in order to do that.
> > > I didn't like the generated WSDL since it used a wrapping "return"
> > 
> > element
> > 
> > > for the type of the wsdl:part for the response
> > > and wanted to get rid of it.
> > > The response element looked like this:
> > > <response>
> > > 
> > >    <return>
> > >    
> > >       <message></message>
> > >     
> > >     </return>
> > > 
> > > </reponse>
> > > 
> > > All i want is a more "direct" type for the reponse without the <return>
> > > element.
> > > I thought about using a ResponseWrapper and created one:
> > > 
> > > @ResponseWrapper(className="test.ResponseWrapper")
> > > Response generateResponse()
> > > 
> > > The generated WSDL looks fine since the type defined in the
> > 
> > ResponseWrapper
> > 
> > > is used directly (no more
> > > wrapping element).
> > > 
> > > Here's the content of the ReponseWrapper:
> > > package test;
> > > 
> > > @XmlRootElement
> > > @XmlType(propOrder = {"message"})
> > > @XmlAccessorType(XmlAccessType.FIELD)
> > > public class ResponseWrapper {
> > > 
> > >      @XmlElement(name="message")
> > >     
> > >     private String message;
> > >     public String getMessage() {
> > >     
> > >          return message;
> > >     
> > >     }
> > >    
> > >    public void setMessage(String aMessage) {
> > >    
> > >        message=aMessage;
> > >    
> > >    }
> > >    
> > >    public void setResponse(Response response) {
> > >    
> > >            this.message=response.getMessage();
> > >    
> > >    }
> > >   
> > >   public Response getResponse() {
> > >   
> > >         return new Response(message);
> > >   
> > >   }
> > > 
> > > }
> > > 
> > > But when i invoke the webservice i never see the <message> element. The
> > > field does not appear in the response.
> > > Maybe i don't understand the usage of the ResponseWrapper and haven't
> > 
> > found
> > 
> > > much information on it .
> > > I added a breakpoint in the setResponse method but it's never reached.
> > > 
> > > Thanks in advance,
> > > Luc
> > 
> > --
> > Daniel Kulp
> > dkulp@apache.org
> > http://dankulp.com/blog

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

Re: @ResponseWrapper usage

Posted by Luc Dewavrin <lu...@gmail.com>.
Ok thanks for the reply.

Actually my Response object does not have only 1 field, it has more (i
simplified my example)
so 2) and 3) won't work.

For 1) yes it would work but actually i don't understand why by default 2
wrapping elements
are created for the response object (in Wrapped mode). As i said, for the
response object i get
the following structure :
<reponse xmlns="urn:mynamespace">
   <return>
     <field1>field1Value</field1>
      <field2>field2Value</field2>
   </return>
</response>

With a Response class like the following one :
@XmlAccessorType(AccessType.FIELD)
public class Response {
   private String field1;
   private String field2;
}

and the wsdl:part is the following :
  <wsdl:message name="Response">
    <wsdl:part element="tns:response" name="parameters">
    </wsdl:part>
  </wsdl:message>
referring to these types:
  <xsd:element name="response" type="tns:Response"></xsd:element>
  <xsd:complexType name="Response">
    <xsd:sequence>
      <xsd:element minOccurs="0" name="return"
type="ns0:Response"></xsd:element>
    </xsd:sequence>
  </xsd:complexType>

I wanted to get rid of the <return> element which i found useless using my
own Response wrapper but
i didn't manage to accomplish it. The generated WSDL looked fine but at
runtime my fields do not appear
in the response element when the method is invoked. I guess i'll have to
switch to BARE mode to make it work.

Luc

On Tue, Sep 28, 2010 at 4:16 PM, Daniel Kulp <dk...@apache.org> wrote:

>
> A few thoughts:
>
> 1) You may just want to switch to BARE mode where you would have complete
> control over the JAXB objects used to form the request/response.
>
> 2) Why not just return a String from the method?
> @WebReturn(name="message")
> String generateResponse(..);
>
> 3) You MAY be able to do this with the wrapper like:
> @XmlElement(name="message")
> Response response
>
> and then adding an @XmlValue to the message thing in the Reponse.  Not
> really
> sure though.
>
> Dan
>
>
> On Tuesday 28 September 2010 9:38:33 am Luc Dewavrin wrote:
> > Hi,
> >
> > i wanted to control the WSDL from a JAXWS webservice endpoint and used a
> > ResponseWrapper in order to do that.
> > I didn't like the generated WSDL since it used a wrapping "return"
> element
> > for the type of the wsdl:part for the response
> > and wanted to get rid of it.
> > The response element looked like this:
> > <response>
> >    <return>
> >       <message></message>
> >     </return>
> > </reponse>
> >
> > All i want is a more "direct" type for the reponse without the <return>
> > element.
> > I thought about using a ResponseWrapper and created one:
> >
> > @ResponseWrapper(className="test.ResponseWrapper")
> > Response generateResponse()
> >
> > The generated WSDL looks fine since the type defined in the
> ResponseWrapper
> > is used directly (no more
> > wrapping element).
> >
> > Here's the content of the ReponseWrapper:
> > package test;
> >
> > @XmlRootElement
> > @XmlType(propOrder = {"message"})
> > @XmlAccessorType(XmlAccessType.FIELD)
> > public class ResponseWrapper {
> >      @XmlElement(name="message")
> >     private String message;
> >     public String getMessage() {
> >          return message;
> >     }
> >
> >    public void setMessage(String aMessage) {
> >        message=aMessage;
> >    }
> >
> >    public void setResponse(Response response) {
> >            this.message=response.getMessage();
> >    }
> >
> >   public Response getResponse() {
> >         return new Response(message);
> >   }
> >
> > }
> >
> > But when i invoke the webservice i never see the <message> element. The
> > field does not appear in the response.
> > Maybe i don't understand the usage of the ResponseWrapper and haven't
> found
> > much information on it .
> > I added a breakpoint in the setResponse method but it's never reached.
> >
> > Thanks in advance,
> > Luc
>
> --
> Daniel Kulp
> dkulp@apache.org
> http://dankulp.com/blog
>

Re: @ResponseWrapper usage

Posted by Daniel Kulp <dk...@apache.org>.
A few thoughts:

1) You may just want to switch to BARE mode where you would have complete 
control over the JAXB objects used to form the request/response.

2) Why not just return a String from the method?   
@WebReturn(name="message")
String generateResponse(..);

3) You MAY be able to do this with the wrapper like:
@XmlElement(name="message")
Response response

and then adding an @XmlValue to the message thing in the Reponse.  Not really 
sure though.

Dan


On Tuesday 28 September 2010 9:38:33 am Luc Dewavrin wrote:
> Hi,
> 
> i wanted to control the WSDL from a JAXWS webservice endpoint and used a
> ResponseWrapper in order to do that.
> I didn't like the generated WSDL since it used a wrapping "return" element
> for the type of the wsdl:part for the response
> and wanted to get rid of it.
> The response element looked like this:
> <response>
>    <return>
>       <message></message>
>     </return>
> </reponse>
> 
> All i want is a more "direct" type for the reponse without the <return>
> element.
> I thought about using a ResponseWrapper and created one:
> 
> @ResponseWrapper(className="test.ResponseWrapper")
> Response generateResponse()
> 
> The generated WSDL looks fine since the type defined in the ResponseWrapper
> is used directly (no more
> wrapping element).
> 
> Here's the content of the ReponseWrapper:
> package test;
> 
> @XmlRootElement
> @XmlType(propOrder = {"message"})
> @XmlAccessorType(XmlAccessType.FIELD)
> public class ResponseWrapper {
>      @XmlElement(name="message")
>     private String message;
>     public String getMessage() {
>          return message;
>     }
> 
>    public void setMessage(String aMessage) {
>        message=aMessage;
>    }
> 
>    public void setResponse(Response response) {
>            this.message=response.getMessage();
>    }
> 
>   public Response getResponse() {
>         return new Response(message);
>   }
> 
> }
> 
> But when i invoke the webservice i never see the <message> element. The
> field does not appear in the response.
> Maybe i don't understand the usage of the ResponseWrapper and haven't found
> much information on it .
> I added a breakpoint in the setResponse method but it's never reached.
> 
> Thanks in advance,
> Luc

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog