[英]How to let generic T type in java annotation?
我正在开发 API 到前端,但许多 API 是相似的,例如:
GET foos
GET foos/{id}
POST foos
PUT foos
DELETE foos/{id}
GET bars
GET bars/{id}
POST bars
PUT bars
DELETE bars/{id}
我想在BaseController
中放置任何通用逻辑以减少开发工作,例如:
public abstract class BaseController<V> {
@GetMapping("/{id}")
@ApiOperation(value = "Get detail info", response = FooVO.class)
protected ApiResult detail(@PathVariable String id) {
V v = getService().getById(id);
return ApiResult.success(v);
}
}
但我也想支持许多具体的控制器:
public class FooController extends BaseController<FooVO>
public class BarController extends BaseController<BarVO>
...
所以响应 class 应该是动态 map 到通用V
@ApiOperation(value = "Get detail info", response = FooVO.class)
==>
@ApiOperation(value = "Get detail info", response = V.class)
但它不编译。
我也尝试了以下方式,仍然无法编译
protected abstract Class<V> getClazz();
@ApiOperation(value = "Get detail info", response = getClazz())
那么任何其他方式可以解决这个问题吗?
注释值必须是常量,因此响应值不能是通用的,因为实际值在编译时未知且不是常量。 也许有一些选择可以绕过这个限制,比如这里的另一个答案,但不是让事情变得更容易的东西。
这不是一个完美的解决方案,但您可以做的最佳选择可能是将逻辑与基本 controller EP 分开,并让继承 class 来填充注释。 因此,在您的基础 class 中类似:
public abstract class BaseController<V> {
protected ApiResult detail(String id) {
V v = getService().getById(id);
return ApiResult.success(v);
}
}
并继承 controller:
public class FooController<FooVO> {
@GetMapping("/{id}")
@ApiOperation(value = "Get detail info", response = FooVO.class)
@Override
protected ApiResult detail(@PathVariable String id) {
return super(id);
}
}
注意:这个例子当然不好,因为这种单一方法实际上不需要 generics 或基本 class 。 该服务可以直接注入和调用,而无需调用 super。 但是,当然,如果您还需要使用 generics 处理其他一些事情 - 在您的方法中的 controller 级别 - 这是下一个最佳选择。
如果您真正担心有类似的 API 端点,您可以尝试 Spring 数据 Rest ZDB9742CE38714CA8DE64FZA87A。 这解决了我们在 Controllers 中所做的重复性工作。
可以参考以下链接:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.