简体   繁体   English

CXF JAXRS | 生成的wadl中不存在复杂响应类型

[英]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. 我们使用cxf 2.5.2和spring来暴露和消费宁静的服务。 For distributing the service interface classes, we started using wadl2java goal (which generates interface classes based on the given wadl file) 为了分发服务接口类,我们开始使用wadl2java目标(根据给定的wadl文件生成接口类)

The generated wadl doesnt contain the proper response type, because of which i guess, the generated interfaces all have 'Response' as the return type. 生成的wadl不包含正确的响应类型,因为我猜测,生成的接口都有'Response'作为返回类型。

Ex. 防爆。 if the restful get method returns 'List' , the generated wadl contains the following segment only: 如果restful get方法返回'List',则生成的wadl仅包含以下段:

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

and the corresponding interface generated from this wadl file contains the return type as 'Response' 并且从该wadl文件生成的相应接口包含返回类型为“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? 是否有任何注释(如ElementClass?如何使用它?)或提供者需要?

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". 也就是说,即使使用“Item”作为返回类型,也会导致生成的界面中的方法返回类型为“Response”。 To remedy this, you need to add the element attribute in the WADL resource response: 要解决此问题,您需要在WADL资源响应中添加element属性:

<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. 如果直接修改WADL,则可以使用,可以支持也可以不支持等效的JAX-RS注释。 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. 我的建议(我之前使用过)是创建一个封装List返回类型的包装列表类型(例如ItemList)。

In either case, you will need to flip from a bottom up to a top down (ie, WADL first) implementation. 在任何一种情况下,您都需要从底部向上翻转到自上而下(即WADL优先)实现。 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. 为了澄清这一切,我基于标准的JAX-RS“Bookstore”示例制作了一个简单的示例项目。 You can view the pom (with the wadl2java configuration) and the actual wadl on github. 您可以在github上查看pom (使用wadl2java配置)和实际的wadl The generated code is there as well (eg, BookstoreidResource.java ). 生成的代码也在那里(例如, 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. 在处理列表,映射等时,我遇到了类似的问题。因为在生成WSDL时集合在运行时不知道它们的类型,所以忽略了放入集合的类型。 The exception to this, I found, was when another web service exposed method used that particular type. 我发现,例外情况是,另一个Web服务公开的方法使用了该特定类型。 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. 因此,例如,我有一个名为User的类,它扩展了一个名为BaseObject的抽象类,该类未被Web服务直接使用。 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. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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