Webservice with CXF: How to use the ResponseWrapper?
Asked Answered
T

1

10

We are creating a webservice (CXF-based) driven by a java class (Java2WS) with the following method:

  @WebMethod
  @RequestWrapper(className = "com.myproject.wrapper.MyRequestWrapper")
  @ResponseWrapper(className = "com.myproject.wrapper.MyResponseWrapper")
  public MyResponse verifyCode(@WebParam(name = "code") String code) {
    ...
    return new MyResponse("Hello",StatusEnum.okay);
  }

I use the wrappers to define the elements of the request resp. response in more detail: the correct element names (which start with an uppercase character), required and optional elements, ...). But I am not sure if this is the right way to do it (there is no in-depth documentation about wrappers, isn't it?)

The class MyResponse:

public class MyResponseWrapper {

  private String result;   
  private ModeEnum status;

  // getters and setters
}

The class MyReponseWrapper

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "myResponse")
public class MyResponseWrapper {

  @XmlElement(name="Result")
  private String result;

  @XmlElement(name = "Status")
  private StatusEnum status;

  public MyResponseWrapper() {
    result="fu"; // just for testing
  }

  // getters and setters
}

Currently I don't understand the Wrappers. When I return an instance of MyReponse, how does the data from MyResponse be injected into MyResponseWrapper respectivly to the SOAP body of the response?

By testing this webservice I can see that an instance of MyResponseWrapper is instantiated and the SOAP body contains the correct elements but with default data (for example: result="fu" instead of "Hello"). I expected that CXF injects matching data from MyResponse to MyResponseWrapper. Is that wrong?

If this is the wrong way to do it: Wat is the right way to specify the resulting SOAP xml when using Java2WS?

By the way: The above source snippets are just examples taken from our more complex (more fields) classes.

Trichome answered 20/11, 2010 at 8:57 Comment(0)
A
1

This is the right way to do it. The request and response wrappers just allow for overriding the xml namespace and element/attribute names for the request/response elements; respectively - which in turn map to the methods used to manage those values.

Ref: http://cxf.apache.org/docs/developing-a-service.html#DevelopingaService-The@RequestWrapperannotation

The @RequestWrapper annotation is defined by the javax.xml.ws.RequestWrapper interface. It is placed on the methods in the SEI. As the name implies, @RequestWrapper specifies the Java class that implements the wrapper bean for the method parameters that are included in the request message sent in a remote invocation. It is also used to specify the element names, and namespaces, used by the runtime when marshalling and unmarshalling the request messages.

The following table describes the properties of the @RequestWrapper annotation.

localName

Specifies the local name of the wrapper element in the XML representation of the request message. The default value is the name of the method or the value of the @WebMethod annotation's operationName property.

targetNamespace

Specifies the namespace under which the XML wrapper element is defined. The default value is the target namespace of the SEI.

className

Specifies the full name of the Java class that implements the wrapper element.

Aalii answered 12/9, 2013 at 19:10 Comment(2)
className property has package name different to the class . Eventhough the full Name is different , webclient is working . What could be the reason?? Example: @WebMethod @RequestWrapper(className = "myproject.com.wrapper.MyRequestWrapper") @ResponseWrapper(className = "myproject.com.wrapper.MyResponseWrapper") public MyResponse verifyCode(@WebParam(name = "code") String code) { ... return new MyResponse("Hello",StatusEnum.okay); }Huntingdon
Many frameworks like Spring or any aspect-oriented-programming (AOP) platform use JVM injection techniques to 'point' a wrapper class to the original and back again such as when creating a "join point". ORM frameworks like Hibernate do the same. This link shows an example of getting the 'actual' className in a log for example: #11506235Aalii

© 2022 - 2024 — McMap. All rights reserved.