2016-03-22 1 views
0

Я новичок в Jersey 2 и JAX-RS, поэтому, вероятно, я чего-то не хватает. То, что я пытаюсь сделать, - это тестовая программа для определения стиля кодирования при разработке служб отдыха. Тест был написан в JAVA и использует JERSEY 2.22.2, JDK 1.8.31, MOXY AS JSON Provider.Проблемы при использовании EntityFilteringFeature и SelectableEntityFilteringFeature с Джерси 2

Я определил ресурс с помощью методов GET для поддержки СПИСОК/ДЕТАЛИ. Из-за размера моего POJO я использовал некоторые фильтры, и все было в порядке.

// 1) First of all I defined the annotation. 


@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
@EntityFiltering 
public @interface MyDetailView { 

public static class Factory extends AnnotationLiteral<MyDetailView> 
    implements MyDetailView { 

    private Factory() { 
    } 

    public static MyDetailView get() { 
     return new Factory(); 
    } 
} 


// 2) Once defined the annotation, I used to 
// programmaticaly exclude the list of subItems in the response... 


@XmlRootElement 
public class MyPojo { 

...  


    //*** THIS SHOULD BE FILTERED IF THE ANNOTATION IS NOT SPECIFIED IN THE RESPONSE *** 
    @MyDetailView 
    private List<SubItem> subItems = new ArrayList<SubItem>(); 

    public List<SubItem> getSubItems() { 
     return subItems; 
    } 

    public void setSubItems(List<SubItem> subItems) { 
     this.subItems = subItems; 
    } 

} 


// 3) I registered the EntityFilteringFeature 

    public class ApplicationConfig extends ResourceConfig { 

    public ApplicationConfig() { 

     .... 
     register(EntityFilteringFeature.class); 

    } 


// 4) Finally, I wrote the code to include/exclude the subItems 


/* 
The Resource class has getCollection() and getItem() methods... 

getCollection() adds the annotation only if filterStyle="detail" 
getItem() always add the annotation 

*/ 

@Path(....) 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class MyResource extends SecuredResource { 

    //filterStyle -> "detail" means MyDetailAnnotation 
    @GET 
    public Response getCollection(
     @QueryParam("filterStyle") String filterStyle, 
     @Context UriInfo uriInfo) { 


     //THIS CODE AFFECTS THE RESPONSE 
     boolean detailedResponse = "detail".equals(filterStyle);  
     Annotation[] responseAnnotations = detailedResponse 
      ? new Annotation[0] 
      : new Annotation[]{MyDetailView.Factory.get()}; 

     //pojo collection...   
     MyPagedCollection myCollection = new MyPagedCollection(); 

     //..... 

     ResponseBuilder builder = Response.ok(); 

     return builder.entity(myCollection, responseAnnotations).build(); 
    } 

    @GET 
    @Path("/{id}") 
    public Response getItem(@PathParam("{id}") String idS, @Context UriInfo uriInfo) { 
     MyPOJO pojo = ... 

     Annotation[] responseAnnotations = new Annotation[]{MyDetailView.Factory.get()}; 

     return Response.ok().entity(pojo, responseAnnotations).build(); 
    } 
} 

После первого теста я пытался использовать SelectableEntityFilteringFeature, чтобы позволить клиенту попросить конкретных полей в деталях, так что я изменил ApplicationConfig

public class ApplicationConfig extends ResourceConfig { 

    public ApplicationConfig() { 

     .... 
     register(EntityFilteringFeature.class); 

     register(SelectableEntityFilteringFeature.class); 
     property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "fields");   
    } 

и я ve добавьте «поля» QueryParam к ресурсу getItem() метод ...

@GET 
@Path("/{id}") 
public Response getDetail(@PathParam({id}) String id, 
     @QueryParam("fields") String fields, 
     @Context UriInfo uriInfo) { 

     .... 

Но пока я зарегистрировал класс SelectableEntityFilteringFeature, класс EntityFilteringFeature перестает работать. Я попытался добавить параметр «поля» в один из методов Resource, он отлично работал. Но MyDetailAnnotation был совершенно бесполезен.

Я пытался зарегистрировать его с помощью DynamicFeature

public class MyDynamicFeature implements DynamicFeature { 

@Override 
public void configure(ResourceInfo resourceInfo, FeatureContext context) { 
    if ("MyResource".equals(resourceInfo.getResourceClass().getSimpleName()) 
       && "getItem".equals(resourceInfo.getResourceMethod().getName())) { 

      //*** IS THE CORRECT WAY TO BIND A FEATURE TO A METHOD? *** 
      // 
      context.register(SelectableEntityFilteringFeature.class); 
      context.property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "fields"); 

    }  
} 

Теперь вопросы:

1) Почему регистрации как функция SelectableEntityFilteringFeature ломает EntityFilteringFeature?

2) Каков правильный способ привязки функции к методу с интерфейсом DynamicFeature?

Заранее спасибо. Это мое первое сообщение в Stack Overflow, я надеюсь, что было написано жалобы на правила.

ответ

0

SelectableEntityFilteringFeature имплицитно регистрирует EntityFilteringFeature (Как упоминалось, here). Поэтому я не вижу необходимости добавлять это.

Поскольку вам нужно Фильтрация на основе аннотаций, вы можете исключить из поляSelectableEntityFilteringFeature.

Вы можете просто сделать,

// Set entity-filtering scope via configuration. 
.property(EntityFilteringFeature.ENTITY_FILTERING_SCOPE, new Annotation[] {MyDetailView.Factory.get()}) 
// Register the EntityFilteringFeature. 
.register(EntityFilteringFeature.class) 
// Further configuration of ResourceConfig. 

Вы можете обратиться к this, например, для использования и this, например, для регистрации фильтра.

Таким образом, вы можете удалить SelectableEntityFilteringFeature и попробовать только вышеуказанный способ его регистрации.

+0

Спасибо. Но это то, что я сделал, и это сработало (единственное различие заключалось в том, что я не указывал свойство в подклассе ResourceConifg, я добавил аннотацию в методе Resource.Теперь моя цель - использовать функцию SelectableEntityFilteringFeature в подробном методе (используя поля QueryParam), для ясности я добавил к этому методу другую подпись метода. В то же время я хочу оставить getCollection() как есть (он фильтрует ответ через аннотацию MyDetailView точно так, как описано в ссылках, которые вы опубликовали). Проблема в том, что неизменная фильтрация getCollection() прекратилась. –

+0

Плакат хочет использовать как EntityFilteringFeature, так и SelectableEntityFilteringFeature, поэтому на самом деле это не ответ. Он просто описывает, как использовать только EntityFilteringFeature на основе аннотаций – ChrisO

Смежные вопросы