У меня есть очень стандартные API, поэтому я создал универсальный контроллер для сопоставления (контроллеры используются только для сопоставления с URL-адресами, все остальное обрабатывается внутри классов службы). Вот упрощенная версия моего контроллера
@RestController
@RequiredArgsConstructor
public abstract class Controller<Entity, Id, BrowseResponse, ShowResponse, Request,
Repository extends com.example.repositories.Repository<Entity, Id>,
Service extends com.example.services.Service<Entity, Id, BrowseResponse, ShowResponse, Request, Repository>> {
protected final Service service;
@GetMapping
@ResponseStatus(HttpStatus.OK)
public List<BrowseResponse> index() {
return service.index();
}
@PostMapping
@ResponseStatus(HttpStatus.OK)
public void create(@Valid @RequestBody Request request) {
service.create(request);
}
@GetMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public ShowResponse show(@PathVariable Id id) {
return service.show(id);
}
@PutMapping("/{id}")
public void update(@Valid @RequestBody Request request, @PathVariable Id id) {
service.update(request, id);
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public void delete(@PathVariable Id id) {
service.delete(id);
}
}
При таком подходе я могу создать конкретный контроллер с меньшим количеством кода, как показано ниже.
@RestController
@RequestMapping("/api/items")
public class ItemController extends Controller<Item, Long, ItemBrowseResponse, ItemShowResponse, ItemRequest, ItemRepository, ItemService> {
public ItemController(ItemService service) {
super(service);
}
Круто, теперь у меня все методы правильно отображены, и мне не нужно их все писать.
моя проблема в том, что у меня есть единственный вариант использования, когда мне нужно получить RequestParam в моей индексной функции. Пример: получить страницу параметров, если я использую разбиение на страницы
Так что теперь, если я переопределю функцию index следующим образом
@GetMapping
@ResponseStatus(HttpStatus.OK)
public List<LevelResponse> index(@RequestParam(defaultValue = "0") Integer page) {
return service.index(page);
}
Я получаю сообщение об ошибке при создании bean-компонента
Уже существует метод bean-компонента itemController.
Я попытался переопределить функцию по умолчанию, подобную этой
@Deprecated
@Override
public List<LevelResponse> index() {
return super.index();
}
Тем не менее, ошибка все еще существует.
Как я могу удалить отображение из унаследованного метода?
Примечание. НЕ рекомендуется использовать общий контроллер, поскольку повторная реализация всех методов будет кошмаром.
Кстати: @Deprecated и @Override являются только аннотациями времени компиляции и ничего не делают во время выполнения.




Попробуйте добавить атрибут params к аннотации @GetMapping в перегруженном методе:
@GetMapping(params = {"page"})
@ResponseStatus(HttpStatus.OK)
public List<LevelResponse> index(@RequestParam(defaultValue = "0") Integer page) {
return service.index(page);
}
См. аналогичный вопрос: Метод контроллера перегрузки в Java Spring
В моем случае мне нужна новая индексная функция в качестве базового сопоставления, но это вдохновило меня на хороший обходной путь.
Как упоминалось в ответе @ursa, я могу использовать перегрузку RequestMapping в качестве обходного пути.
Поскольку RequestMapping позволяет создавать несколько функций для работы с разными параметрами RequestParams. Я смог переопределить исходную функцию index, чтобы иметь дело только с параметром-заполнителем следующим образом:
@Deprecated
@GetMapping(params = {"deprecated"})
@ResponseStatus(HttpStatus.OK)
@Override
public List<ItemResponse> index() {
return super.index();
}
Таким образом, я могу использовать сопоставление по умолчанию, как мне нужно.
@GetMapping
@ResponseStatus(HttpStatus.OK)
public List<ItemResponse> index(...params) {
return service.index(departmentId);
}
Он не удаляет полностью старую реализацию, но ограничивает ее использованием параметра deprecated, который на самом деле может быть полезен.
Похоже, вам следует переосмыслить наследственность. Возможно, вам нужен
GenericConcontroller, который не имеет метода index и расширяетGenericControllerWithIndex, который реализует этот метод. Amd, чем расширить конкретный контроллер от этого, который вам нужен