2013-02-21 22 views
8

Chúng tôi đang sử dụng Jersey để thực hiện RESTful API bằng cách sử dụng tính năng thú vị của thế hệ WADL tự động.Bao gồm các giá trị có thể có của @PathParam vào WADL

Cũng như một ví dụ chúng ta có phương pháp

@GET 
@Path("/{id}/{attribute}") 
@Produces(MediaType.APPLICATION_JSON) 
public Object getAttributeByID(@PathParam("id") long id, @PathParam("attribute") String attribute) { 
.... 
} 

này tạo ra các đoạn sau đây trong WADL:

<param type="xs:string" style="template" name="attribute:.*"/> 

Thuộc tính có thể name, type, size và chúng tôi muốn không chỉ để xác nhận giá trị tại thời gian chạy nhưng cũng hiển thị nó trong wadl tạo ra Theo this document tính năng như vậy nên được hỗ trợ bằng cách tạo ra một số thẻ <option> bên trong <param>, tôi Tôi mong đợi một cái gì đó như sau:

<param type="aws:Attributes" style="template" name="attribute"> 
    <option value="name"/> 
    <option value="type"/> 
    <option value="size"/> 
</param> 

Vấn đề của tôi là kích hoạt nó với Jersey. Nếu thất bại trong việc tìm tài liệu có liên quan và cho rằng có lẽ nếu tôi thay đổi kiểu của tham số từ String để enum tính năng này sẽ làm việc tự động, vì vậy tôi đã thay đổi chữ ký phương pháp để:

@Path("/{id}/{attribute}") 
@Produces(MediaType.APPLICATION_JSON) 
public Object getAttributeByID(@PathParam("id") long id, @PathParam("attribute") Attribute attribute) { 
.... 
} 

nơi

public enum Attribute { 
    name, type, size 
} 

nhưng Jersey vẫn tạo thẻ <param> mà không có tùy chọn và loại tham số vẫn là xs:string.

Tôi đã cố gắng tìm nó trong mã của Jersey và tìm thấy lớp học com.sun.research.ws.wadl.Option với chú thích JAXB có liên quan, vì vậy nó có vẻ có liên quan, nhưng tôi không biết cách làm cho nó hoạt động. Tôi đoán vấn đề là trong WadlGeneratorConfig.

Dưới đây là một phần liên quan của định nghĩa Jersey trong chúng tôi 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> 

nơi OurWADLGenerator code is:

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(); 
    } 
} 

tôi thiếu gì ở đây? Cảm ơn trước.

+0

'enum công cộng Attribure' nên được 'công khai enum thuộc tính' ... nó đã được sao chép từ mã của bạn hoặc chỉ là một lỗi đánh máy? –

+0

@martinjakubik, chắc chắn đó là lỗi đánh máy. Cảm ơn bạn. Tôi vừa chỉnh sửa bài đăng và sửa lỗi này. – AlexR

Trả lời

2

Sau vài cuộc điều tra tôi đã không tìm thấy bất kỳ mã trong jersey nơi danh sách tùy chọn được phổ biến. (Có thể là cái gì đó được chưa được hỗ trợ)

Vì vậy, bạn có thể thực hiện WadlGenerator của riêng bạn và chèn nó chuỗi máy phát điện.

Đây là một mẫu OptionsWadlGenerator thêm <option> yếu tố cho tham số của kiểu 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  
} 

Và tất nhiên, để chèn nó trong chuỗi của bạn, làm một cái gì đó như thế:

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(); 
    } 
} 
3

Tìm kiếm nhanh về tập quán com.sun.research.ws.wadl.Param.getOption() (xem kết quả here) cho thấy rằng nó thực sự không bao giờ được gọi từ thư viện. Tôi đoán nó chỉ có bởi vì các lớp này được tạo ra bởi xjc từ wadl.xsd. Có vẻ như mặc dù Jersey về cơ bản bỏ qua phần thông tin này trong các tệp wadl, và tương tự như vậy không quan tâm đến việc đưa nó vào các tệp wadl mà nó tạo ra.

Một vài năm trước, chúng tôi đã kết thúc viết mã riêng của chúng tôi để tạo wadl, bởi vì công cụ có sẵn rất kém. Điều này có thể đã thay đổi kể từ đó, nhưng vấn đề trên cho thấy rằng hỗ trợ thích hợp cho wadl vẫn không hoàn toàn ở đó. :(

+0

Cảm ơn bạn đã nỗ lực. Tôi cũng không thấy bất kỳ tham chiếu đến chức năng này nhưng cho rằng nó có thể được gọi bằng cách nào đó bằng cách phản chiếu. – AlexR

+0

Chỉ có một vài người triển khai 'WadlGenerator', và' createParam() 'không phức tạp lắm, vì vậy tôi kết luận rằng danh sách tùy chọn bị bỏ qua nếu không có tham chiếu đến getter của nó. – zagyi

Các vấn đề liên quan