有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

spring boot如何在java注释中使用泛型T类型?

我正在为前端开发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> 
...

所以响应类应该动态映射到泛型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())

那么有没有其他方法可以解决这个问题


共 (2) 个答案

  1. # 1 楼答案

    如果您真正关心的是有类似的API端点,那么可以尝试Spring Data Rest API。 这就解决了我们在控制器中重复工作的问题

    可参考以下链接:

    https://www.baeldung.com/spring-data-rest-intro

  2. # 2 楼答案

    注释值必须是常量,因此响应值不能是泛型的,因为实际值在编译时未知,也不是常量。也许有一些方法可以绕过这个限制,比如another answer here,但不能让事情变得更简单

    这不是一个完美的解决方案,但可能最好的选择是将逻辑与基本控制器EP分离,并让继承类填充注释。比如在你的基础课上:

    public abstract class BaseController<V> {
        protected ApiResult detail(String id) {
            V v = getService().getById(id);
            return ApiResult.success(v);
        }
    }
    

    在继承控制器中:

    public class FooController<FooVO> {
        @GetMapping("/{id}")
        @ApiOperation(value = "Get detail info", response = FooVO.class)
        @Override
        protected ApiResult detail(@PathVariable String id) {
            return super(id);
        }
    }
    

    注意:这个例子当然不好,因为这个方法实际上不需要泛型或基类。服务可以直接注入和调用,而无需调用super。当然,如果你需要处理泛型的其他一些事情——在方法的控制器级别——这是下一个最好的选择