The problem is when controller extends base generic abstract class and implements interface with @RequestMapping it has mapped only those methods which signature have pure generic type. Other methods mapped only if controller's subclass overrides those methods. To represent an issue, lets imagine the following project structure (or visit this example repo): Generic repository interface:

public interface IRepository<T> {
    Optional<T> get(Long id);
    List<T> getALl();
    T save(T t);
}

…its implementation:

@Component
public class IntegerRepository implements IRepository<Integer> {
    @Override
    public Optional<Integer> get(Long id) {
        return Optional.of(10);
    }

    @Override
    public List<Integer> getALl() {
        return Arrays.asList(10,20,30);
    }

    @Override
    public Integer save(Integer integer) {
        return integer;
    }
}

Generic abstract controller class:

public abstract class AController<T> {

    private IRepository<T> repository;

    public AController(IRepository<T> repository) {
        this.repository = repository;
    }

    public Optional<T> get(Long id) {
        return repository.get(id);
    }

    public List<T> getAll() {
        return repository.getALl();
    }

    public T post(T t) {
        return repository.save(t);
    }
}

Controller interface:

@RequestMapping("/integers")
public interface IntegerController {
    @RequestMapping(method = RequestMethod.GET, value = "/{id}")
    Optional<Integer> get(@PathVariable Long id);

    @RequestMapping(method = RequestMethod.GET)
    List<Integer> getAll();

    @RequestMapping(method = RequestMethod.POST)
    Integer post(@RequestBody Integer t);
}

…and its implementation:

@RestController
public class IntegerControllerImpl extends AController<Integer> implements IntegerController {
    @Autowired
    public IntegerControllerImpl(IntegerRepository repository) {
        super(repository);
    }
}

In this case Spring doesn’t map controller’s get() and getAll() methods but post() do.

2020-05-16 09:44:51.347 TRACE 5437 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : c.a.s.c.IntegerControllerImpl: {POST /integers}: post(Integer)

The only way to make it work is to override base controller's GET methods.

@RestController
public class IntegerControllerImpl extends AController<Integer> implements IntegerController {
    @Autowired
    public IntegerControllerImpl(IntegerRepository repository) {
        super(repository);
    }

    @Override
    public Optional<Integer> get(Long id) {
        return super.get(id);
    }

    @Override
    public List<Integer> getAll() {
        return super.getAll();
    }
}

2020-05-16 13:54:12.843 TRACE 5914 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : c.a.s.c.IntegerControllerImpl: {GET /integers/{id}}: get(Long) {GET /integers}: getAll() {POST /integers}: post(Integer)

Comment From: jhonynet

I have the same issue :(

Comment From: snicoll

It's hard to put pieces together here. In particular you. Perhaps this note in the doc helps (i.e. adding @Controller on the interface as well or use class-based proxies).

If it does not, please move that code in a small sample we can use to reproduce the problem you've described. You can attach a zip to this issue or push the code to a separate GitHub repository.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.