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