Ich denke, das ist eine generische Java-Frage, aber ich werde erklären, was ich versuche zu tun und hoffentlich kann mir jemand den richtigen Weg zeigen;Dropwizard Zusammenfassung Ressource Design
Ich versuche eine generische abstrakte Klasse zu erstellen, von der alle meine Ressourcen profitieren können.
Die abstrakte Klasse hat grundlegende CRUD Implementierungen für die Standard-Sachen
@Produces("application/vnd.api+json")
@Consumes("application/vnd.api+json")
public abstract class AbstractResource {
static final Logger LOGGER = LoggerFactory.getLogger(AbstractResource.class);
AbstractRepository repository;
AbstractResource(AbstractRepository repository) {
this.repository = repository;
}
@GET
public Response getAll(@Auth User user, @QueryParam("query") String query) {
String result = query != null ? repository.getByQuery(query) : repository.getAll();
return Response.status(Response.Status.OK).entity(result).build();
}
@GET
@Path("/{id}")
public Response getById(@Auth User user, @PathParam("id") String id) {
String result = repository.getById(id);
return Response.status(Response.Status.OK).entity(result).build();
}
@POST
public Response save(@Auth User user, String payload) {
String result = repository.save(payload);
return Response.status(Response.Status.OK).entity(result).build();
}
@PATCH
@Path("/{id}")
public Response update(@Auth User user, @PathParam("id") String id, String payload) {
String result = repository.update(payload);
return Response.status(Response.Status.OK).entity(result).build();
}
@DELETE
@Path("/{id}")
public Response delete(@Auth User user, @PathParam("id") String id) {
repository.delete(id);
return Response.status(Response.Status.NO_CONTENT).build();
}
}
Ich kann dies einfach ohne Probleme verwenden
@Path("/movies")
public class MovieResource extends AbstractResource {
public MovieResource(MovieRepository repository) {
super(repository);
}
}
tun und ich kann nun alle Methoden zugreifen und außer Kraft setzen, wie erforderlich .
Wo ich auf Probleme stoße ist, wenn ich eine Methode überladen muss. Nehmen Sie die erste getAll
Methode von der abstrakten Klasse als Beispiel möchte ich in die Parameter ändern, dass nur die Movie.class
@Path("/movies")
public class MovieResource extends AbstractResource {
public MovieResource(MovieRepository repository) {
super(repository);
}
@GET
public Response getAll(@Auth User user, @QueryParam("query") String query, @QueryParam("limit") String limit, @QueryParam("page") String page) {
String result = repository.getPaginated(limit, page);
return Response.status(Response.Status.OK).entity(result).build();
}
}
So ist die getAll
Methode hat einen anderen Satz von Parametern in genau der Movie.class
. Dies bewirkt, dass Jersey sprengen mit
[[FATAL] A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by"@Consumes" and "@Produces" annotations at Java methods public javax.ws.rs.core.Response space.cuttlefish.domain.resources.MovieResource.getAll(space.cuttlefish.domain.model.User,java.lang.String,java.lang.String,java.lang.String) and public javax.ws.rs.core.Response space.cuttlefish.domain.resources.AbstractResource.getAll(space.cuttlefish.domain.model.User,java.lang.String) at matching regular expression /movies. These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.; source='[email protected]']
Da die ursprünglichen getAll
Methode der abstrakten bereits die @GET
Annotation hat.
Also, wie gehe ich über die Lösung dieses Problems?
Lösche ich alle Anmerkungen aus der abstrakten Klasse und muss dann die Anmerkungen in jeder Ressource überschreiben und erneut hinzufügen? Das scheint einfach chaotisch und fehleranfällig ... Hier muss es eine bessere Lösung geben?
Gibt es etwas blendend offensichtliche, das ich gerade übersehen habe?
Ich würde gerne etwas Hilfe!
Wenn Sie nicht alle Subklassen wollen die getAll Methode mit der kürzeren Signatur haben, sollte es nicht in der abstrakten Basisklasse sein. Die geerbte Methode verursacht hier sicherlich Probleme. Möglicherweise möchten Sie der Frage ein Jersey- oder JAX-RS-Tag hinzufügen. – JayK
Danke für den Tag Tipp; Hmm, das ist, was ich im Moment gemacht habe, scheint albern, obwohl ich den gleichen Code in 20 verschiedene Klassen kopiere, um den Fall zu lösen, wo nur eine Klasse die Dinge anders behandelt. –
Ein Mixin-Mechanismus wäre sicher schön. Eine sehr vage Antwort wäre "Komposition über Vererbung", aber da ich JAX-RS bisher noch nie benutzt habe, weiß ich nicht, ob dieses Mantra hier auf eine nette Art und Weise angewendet werden kann. – JayK