2012-01-04 13 views
6

Tôi đã có một chức năng như:Ở Jersey, tôi có thể kết hợp QueryParams và FormParams thành một giá trị cho một phương thức không?

@POST 
@Path("/create") 
@Produces({MediaType.APPLICATION_JSON}) 
public Playlist createPlaylist(@FormParam("name") String name) 
{ 
    Playlist p = playlistDao.create(); 
    p.setName(name); 
    playlistDao.insert(p); 
    return p; 
} 

Tôi muốn các "tên" tham số đến từ các hình thức HOẶC từ tham số truy vấn. Nếu người dùng đăng lên/playlist/create /? Name = bob thì tôi muốn nó hoạt động. (Điều này chủ yếu là để hỗ trợ kiểm tra API, nhưng cũng để tiêu thụ nó trên các nền tảng không phải trình duyệt khác nhau.)

Tôi sẵn sàng phân lớp mọi thứ làm cho công việc liên kết ma thuật ... (@BothParam ("name ") String name) nhưng sẽ cần một số trợ giúp để làm điều đó xảy ra khi tôi mới sử dụng Jersey/Java Servlets.


Cập nhật: Ngày hôm sau ...

Tôi đã giải quyết điều này bằng cách thực hiện một ContainerRequestFilter rằng sáp nhập các thông số form vào một tham số truy vấn. Đây không phải là giải pháp tốt nhất, nhưng nó dường như hoạt động. Tôi không có bất kỳ may mắn sáp nhập bất cứ điều gì vào các tham số biểu mẫu.

Dưới đây là mã trong trường hợp ai đó đi kèm tìm kiếm nó:

@Override 
public ContainerRequest filter(ContainerRequest request) 
{ 
    MultivaluedMap<String, String> qParams = request.getQueryParameters(); 
    Form fParams = request.getFormParameters(); 
    for(String key : fParams.keySet()) 
    { 
     String value = fParams.get(key).get(0); 
     qParams.add(key, value); 
    } 
} 

tôi sẽ vẫn đánh giá cao biết nếu có một cách tốt hơn để làm điều này vì vậy tôi sẽ để lại câu hỏi này mở cho bây giờ.

Trả lời

3

Một cách bạn có thể thực hiện việc này là với InjectableProvider.

Trước tiên, bạn muốn xác định một chú thích BothParam:

@Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD }) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface BothParam { String value(); } 

Sau đó, xác định một InjectableProvider cho nó:

@Provider 
public class BothParamProvider implements Injectable<String>, InjectableProvider<BothParam, Type> {  
    @Context private HttpContext httpContext; 
    private String parameterName; 

    public BothParamProvider(@Context HttpContext httpContext) { 
     this.httpContext = httpContext; 
    } 

    public String getValue() {   
     if (httpContext.getRequest().getQueryParameters().containsKey(parameterName)) { 
      return httpContext.getRequest().getQueryParameters().getFirst(parameterName); 
     } else if(httpContext.getRequest().getFormParameters().containsKey(parameterName)) { 
      return httpContext.getRequest().getFormParameters().getFirst(parameterName); 
     } 
     return null; 
    } 

    public ComponentScope getScope() { 
     return ComponentScope.PerRequest; 
    } 

    public Injectable getInjectable(ComponentContext cc, BothParam a, Type c) {   
     parameterName = a.value(); 
     return this; 
    }  
} 

Lưu ý, đây không phải là thực sự là một khớp nối của QueryParamFormParam. Các mục tiêu được chú thích với một trong hai mục tiêu đó được tiêm theo cách tinh vi hơn nhiều. Tuy nhiên, nếu nhu cầu của bạn đủ giới hạn, phương pháp được nêu ở trên có thể phù hợp với bạn.

+0

Tôi không thể tìm thấy lớp Injectable và InjectableProvider. Họ có bị loại bỏ trong thư viện Jersey gần đây không? Có sự thay thế nào không? –

+0

Nếu gần đây, bạn có đề cập đến bản phát hành 2.x, thì, vâng, tôi tin rằng có sự thay thế - http://stackoverflow.com/questions/18463311/jersey-2-how-to-replace-injectableprovider -and-abstracthttpcontextinjectable – maxenglander

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