Spring Boot — как удалить RequestMapping из унаследованного метода

У меня есть очень стандартные 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();
}

Тем не менее, ошибка все еще существует.

Как я могу удалить отображение из унаследованного метода?

Примечание. НЕ рекомендуется использовать общий контроллер, поскольку повторная реализация всех методов будет кошмаром.

Похоже, вам следует переосмыслить наследственность. Возможно, вам нужен GenericConcontroller, который не имеет метода index и расширяет GenericControllerWithIndex, который реализует этот метод. Amd, чем расширить конкретный контроллер от этого, который вам нужен

Jens 12.04.2023 15:36

Кстати: @Deprecated и @Override являются только аннотациями времени компиляции и ничего не делают во время выполнения.

Jens 12.04.2023 15:37
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте добавить атрибут params к аннотации @GetMapping в перегруженном методе:

@GetMapping(params = {"page"})
@ResponseStatus(HttpStatus.OK)
public List<LevelResponse> index(@RequestParam(defaultValue = "0") Integer page) {
    return service.index(page);
}

См. аналогичный вопрос: Метод контроллера перегрузки в Java Spring

В моем случае мне нужна новая индексная функция в качестве базового сопоставления, но это вдохновило меня на хороший обходной путь.

galalem 12.04.2023 16:12
Ответ принят как подходящий

Как упоминалось в ответе @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, который на самом деле может быть полезен.

Другие вопросы по теме