【问题标题】:Spring generic abstract controller and interface GET/DELETE methods mappingSpring 通用抽象控制器和接口 GET/DELETE 方法映射
【发布时间】:2020-05-16 07:04:01
【问题描述】:

春季启动 2.2.7。 让我们想象下一个项目结构:

通用存储库接口:

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

…它的实现:

@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;
    }
}

通用抽象控制器类:

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);
    }
}

控制器接口:

@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);
}

…及其实现:

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

为什么 Spring 不映射控制器的 get()getAll() 方法而 post() 映射?

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)

UPD。我做了一些研究,发现如果控制器子类将覆盖 GET/DELETE 方法(PUT 和 POST 运行良好),它将按预期工作。因此,由于泛型,似乎不支持这些 HTTP 方法从超类继承此类行为......但是,也许稍后我会在 spring MVC GitHub repo 上打开这个案例的问题。

@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)

This Example GitHub

【问题讨论】:

  • 您没有显示足够的控制器主体来分辨。 (请注意,在实际代码中,Spring Data 可以自动为您处理其中的三分之二。)
  • @chrylis-onstrike- 感谢您查看问题。至于您对 Spring Data 的建议,我知道。为了简化对我的问题的理解,我在这种情况下故意省略了它。控制器的主体在 AController 类中。

标签: java spring rest spring-mvc


【解决方案1】:

我做了一些额外的研究,调试了 Spring,发现在这种特殊情况下 RequestMappingHandlerMapping bean 不能解析签名纯泛型返回类型中没有的方法。不能确定是反射故障/功能还是 Spring 处理程序的逻辑。尽管如此,我还是在 Spring 存储库上打开了一个 issue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 2015-07-09
    • 1970-01-01
    • 2012-10-25
    相关资源
    最近更新 更多