简体   繁体   中英

CXF JAXRS | Complex response types are not present in the generated wadl

We use cxf 2.5.2 along with spring for exposing and consuming restful services. For distributing the service interface classes, we started using wadl2java goal (which generates interface classes based on the given wadl file)

The generated wadl doesnt contain the proper response type, because of which i guess, the generated interfaces all have 'Response' as the return type.

Ex. if the restful get method returns 'List' , the generated wadl contains the following segment only:

<response><representation mediaType="application/json"/></response>

and the corresponding interface generated from this wadl file contains the return type as 'Response'

Can someone suggest what needs to be done to prevent the actual response type from getting lost? Are any annotations (like ElementClass ? how to use it ?) or providers required?

Current code:

@GET
@Path("/itemsForCategory")
@Produces("application/json")
@Description("getItemsForCategory")
public List<Item> getItemsForCategory(@QueryParam("category")String category) {

The generic "Response" return type seems to be unrelated to the fact that you are trying to return a list. That is, even using "Item" as the return type would result in a method in the generated interface with a return type of "Response". To remedy this, you need to add the element attribute in the WADL resource response:

<response><representation mediaType="application/json" element="item"/></response>

This works if you modify the WADL directly, an equivalent JAX-RS annotation may or may not be supported. This also does not address your problem returning a list. My suggestion (which I have previously used) is to create a wrapper list type (eg ItemList) that encapsulates the List return type.

In either case, you will need to flip from a bottom up to a top down (ie, WADL first) implementation. This should not be too bad, since you already have the implementation and you can just make it implement the generated interface.

To clarify all this, I made a simple example project based on the standard JAX-RS "Bookstore" example. You can view the pom (with the wadl2java configuration) and the actual wadl on github. The generated code is there as well (eg, BookstoreidResource.java ).

I had similar issues when dealing with lists, maps etc. Because collections don't know their type at runtime when generating a WSDL the types that you put into the collection are ignored. The exception to this, I found, was when another web service exposed method used that particular type. As a work around I created a dummy method that used every type I needed for lists and maps.

So for example, I had a class called User that extended an abstract class called BaseObject that was not used directly by the webservice. However it was sometimes passed through lists when searching for users. The following code was my workaround.

@WebService
public interface MyService
{
    // Various @WebMethods here

    /**
     * This method should not be used. This is a workaround to ensure that
     * User is known to the JAXB context. Otherwise you will get exceptions like this:
     * javax.xml.bind.JAXBException: class java.util.User nor any of its super class is known to this context.
     * Or it will assume that using BaseObject is OK and deserialisation will fail
     * since BaseObject is abstract.
     * This issue occurs because the classes available to the JAXB context
     * are loaded when the endpoint is published. At that time it is not known
     * that User will be needed since it is not explicitly referenced
     * in any of these methods. Adding user here will cause it to be added to
     * the context.
     * @param user
     * @return
     */
    @WebMethod
    void dummy(@WebParam(name="user") User user);
}

I admit this is a bit of a nasty work around and I don't consider it a proper fix, but maybe it will keep you going until someone can provide a better solution.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM