Ich bin neu in Jersey 2 und JAX-RS, also vermisse ich wahrscheinlich etwas. Was ich versuche zu tun ist ein Testprogramm, um einen Codierungsstil bei der Entwicklung von Restdiensten zu definieren. Der Test wurde in JAVA geschrieben und verwendet JERSEY 2.22.2, JDK 1.8.31, MOXY AS JSON Provider.Probleme bei der Verwendung von EntityFilteringFeature und SelectableEntityFilteringFeature mit Jersey 2
Ich habe eine Ressource mit GET-Methoden zur Unterstützung von LIST/DETAIL definiert. Aufgrund der Größe meines POJO habe ich einige Filter benutzt und alles war in Ordnung.
// 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();
}
}
Nach dem ersten Test habe ich versucht, die SelectableEntityFilteringFeature zu verwenden, damit der Client für bestimmte Felder im Detail zu fragen, so änderte ich den ApplicationConfig
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
....
register(EntityFilteringFeature.class);
register(SelectableEntityFilteringFeature.class);
property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "fields");
}
und ich Fügen Sie die "fields" QueryParam zur Resource getItem() -Methode hinzu ...
Solange jedoch die SelectableEntityFilteringFeature-Klasse registriert wurde, hat die EntityFilteringFeature-Klasse nicht mehr funktioniert. Ich habe versucht, "fields" -Parameter zu einer der Resource-Methoden hinzuzufügen, es hat perfekt funktioniert. Aber die MyDetailAnnotation war völlig nutzlos.
Ich habe versucht, es zu registrieren einen DynamicFeature mit
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");
}
}
nun die Fragen:
1) Warum registrieren sowohl die SelectableEntityFilteringFeature Funktion des EntityFilteringFeature bricht?
2) Was ist die korrekte Methode zum Binden eines Features an eine Methode mit der DynamicFeature-Schnittstelle?
Vielen Dank im Voraus. Dies ist mein erster Beitrag zu Stack Overflow, ich hoffe, es wurde geschrieben, beschweren die Regeln.
Danke. Aber das ist, was ich getan habe und es funktioniert (der einzige Unterschied war, dass ich die Eigenschaft in der ResourceConifg-Unterklasse nicht angegeben habe, ich habe die Annotation in der Resource-Methode hinzugefügt.Mein Ziel ist es jetzt, das SelectableEntityFilteringFeature in der Detailmethode zu verwenden (unter Verwendung der QueryParam "fields", um die Übersichtlichkeit zu verbessern, habe ich dem Code die unterschiedliche Methodensignatur hinzugefügt). In der Zwischenzeit möchte ich die getCollection() so lassen, wie sie ist (sie filtert die Antwort über MyDetailView Annotation genau wie in den von Ihnen geposteten Links erklärt). Das Problem ist, dass die unveränderte getCollection() die Filterung beendet hat. –
Das Poster möchte sowohl EntityFilteringFeature als auch SelectableEntityFilteringFeature verwenden, daher ist dies keine wirkliche Antwort. Es beschreibt nur, wie nur Annotation-basierte EntityFilteringFeature verwendet wird – ChrisO