我们正在使用Jersey来实现RESTful API,利用其自动WADL生成的强大功能。
就像一个例子我们有方法
@GET
@Path("/{id}/{attribute}")
@Produces(MediaType.APPLICATION_JSON)
public Object getAttributeByID(@PathParam("id") long id, @PathParam("attribute") String attribute) {
....
}
这会在WADL中生成以下片段:
<param type="xs:string" style="template" name="attribute:.*"/>
属性可以是name
,type
,size
,我们不仅要在运行时验证值,还要在生成的wadl中显示它。根据this document这样的功能应该通过在<option>
内生成多个标记<param>
来支持,即我期待以下内容:
<param type="aws:Attributes" style="template" name="attribute">
<option value="name"/>
<option value="type"/>
<option value="size"/>
</param>
我的问题是用泽西岛启用它。如果找不到相关文档并假设我可能会将参数类型从String
更改为enum
,则此功能会自动生效,因此我将方法签名更改为:
@Path("/{id}/{attribute}")
@Produces(MediaType.APPLICATION_JSON)
public Object getAttributeByID(@PathParam("id") long id, @PathParam("attribute") Attribute attribute) {
....
}
,其中
public enum Attribute {
name, type, size
}
但泽西岛仍然生成<param>
标签而没有选项,参数类型仍为xs:string
。
我试图在Jersey的代码中找到它并找到带有相关JAXB注释的类com.sun.research.ws.wadl.Option
,所以它似乎是相关的,但我不知道如何让它工作。我想问题出在WadlGeneratorConfig
。
以下是我们web.xml
<filter>
<filter-name>REST-API</filter-name>
<filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
................
<init-param>
<param-name>com.sun.jersey.config.property.WadlGeneratorConfig</param-name>
<param-value>com.mycompany.resource.OurWADLGenerator</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.mycompany</param-value>
</init-param>
</filter>
其中OurWADLGenerator
代码为:
public class OurWADLGenerator extends WadlGeneratorConfig {
@Override
public List<WadlGeneratorDescription> configure() {
return generator(WadlGeneratorApplicationDoc.class)
.prop("applicationDocsStream", "application-doc.xml")
.generator(WadlGeneratorResourceDocSupport.class)
.prop("resourceDocStream", "resourcedoc.xml").descriptions();
}
}
我在这里缺少什么? 提前致谢。
答案 0 :(得分:3)
快速搜索com.sun.research.ws.wadl.Param.getOption()
的用法(请参阅结果here)表明它实际上从未从库中调用过。我想这只是因为这些类是由wadl.xsd的xjc生成的。看来,泽西岛基本上忽略了wadl文件中的这条信息,同样也不关心将它包含在它生成的wadl文件中。
几年前,我们最终编写了自己的代码来生成wadl,因为可用的工具非常糟糕。从那时起,这可能已经发生了变化,但上述问题表明对wadl的适当支持仍然不存在。 :(
答案 1 :(得分:2)
经过一些调查后,我没有在球衣中找到填充选项列表的任何代码。 (可能尚不支持)
因此,您可以实现自己的WadlGenerator并将其插入生成器链。
以下为OptionsWadlGenerator
类型参数添加<option>
元素的示例Enum
package com.mycompany;
import com.sun.jersey.api.model.AbstractMethod;
import com.sun.jersey.api.model.AbstractResource;
import com.sun.jersey.api.model.AbstractResourceMethod;
import com.sun.jersey.api.model.Parameter;
import com.sun.jersey.server.wadl.WadlGenerator;
import com.sun.research.ws.wadl.Application;
import com.sun.research.ws.wadl.Method;
import com.sun.research.ws.wadl.ObjectFactory;
import com.sun.research.ws.wadl.Option;
import com.sun.research.ws.wadl.Param;
import com.sun.research.ws.wadl.RepresentationType;
import com.sun.research.ws.wadl.Request;
import com.sun.research.ws.wadl.Resource;
import com.sun.research.ws.wadl.Resources;
import com.sun.research.ws.wadl.Response;
import javax.ws.rs.core.MediaType;
public class OptionsWadlGenerator implements WadlGenerator {
private WadlGenerator _delegate;
private ObjectFactory objectFactory = new ObjectFactory();
@Override
public Param createParam(AbstractResource r, AbstractMethod m, Parameter p) {
Param param = _delegate.createParam(r, m, p);
if(((Parameter)p).getParameterClass().isEnum()){
Object[] values = p.getParameterClass().getEnumConstants();
for(Object enumItem:values){
Option option = objectFactory.createOption();
option.setValue(((Enum)enumItem).name());
param.getOption().add(option);
}
}
return param;
}
@Override
public void setWadlGeneratorDelegate(WadlGenerator delegate) {
this._delegate = delegate;
}
@Override
public Application createApplication() {
return _delegate.createApplication();
}
... all other methods also simply call the _delegate equivalent method
}
当然,要将它插入您的链中,请执行以下操作:
public class OurWADLGenerator extends WadlGeneratorConfig {
@Override
public List<WadlGeneratorDescription> configure() {
return generator(WadlGeneratorApplicationDoc.class)
.prop("applicationDocsStream", "application-doc.xml")
.generator(WadlGeneratorResourceDocSupport.class)
.prop("resourceDocStream", "resourcedoc.xml")
.generator(OptionsWadlGenerator.class).descriptions();
}
}