Я думаю, что это более общий вопрос Java, но я объясню, что я пытаюсь сделать, и, надеюсь, кто-то может указать мне правильный путь;Дизайн абстрактных ресурсов Dropwizard
Я пытаюсь создать общий абстрактный класс, из которого могут простираться все мои ресурсы.
Абстрактный класс имеет базовые реализации CRUD для стандартного материала
@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();
}
}
я могу использовать это без проблем просто делает
@Path("/movies")
public class MovieResource extends AbstractResource {
public MovieResource(MovieRepository repository) {
super(repository);
}
}
и теперь я могу получить доступ ко всем методам и переопределить в соответствии с требованиями ,
Где я столкнулся с проблемами, когда мне нужно перегрузить метод. Возьмите первый getAll
метод из абстрактного класса, как, например, я хочу, чтобы изменить параметры только 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();
}
}
Так метод getAll
имеет другой набор параметров в просто Movie.class
. Это приводит к тому Джерси, чтобы взорвать с
[[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]']
Поскольку исходный getAll
метод реферата уже имеет @GET
аннотацию.
Итак, как мне решить это?
Удалить все аннотации из абстрактного класса, а затем переопределить и повторно добавить аннотации в каждый ресурс? Это просто кажется грязным и подверженным ошибкам ... Здесь должно быть лучшее решение?
Есть ли что-то ослепительно очевидное, я только что забыл?
Хотел бы помочь!
Если вы не хотите, чтобы все подклассы иметь метод GETALL с короткой подписью, он не должен быть в абстрактном базовом классе. Унаследованный метод, безусловно, вызывает проблемы. Вы можете добавить тег Джерси или JAX-RS к вопросу. – JayK
Спасибо за отзыв тега; Хм, это то, что я сделал на данный момент, кажется глупым, хотя копирование одного и того же кода на 20 разных классов для решения в случае, когда только один класс обрабатывает разные вещи. –
Механизм микширования был бы хорош, конечно. Очень расплывчатым ответом будет «состав над наследованием», но поскольку я до сих пор не использовал JAX-RS, я не знаю, можно ли применить эту мантру здесь красиво. – JayK