Spring REST API Swagger UI @ModelAttribute 请求URL 和参数类型

Spring REST API Swagger UI @ModelAttribute request URL and parameter type

我在尝试让我的招摇 UI return 成为我想要的东西时遇到了一些问题。 问题是我想将 areaName 显示为 path 参数类型,而不是 Swagger UI 中的 query。我可以通过使用 @PathVariable String "areaName".

来做到这一点

但是我想在单独的请求类中验证区域名称,现在我正在尝试使用 @Valid @ModelAttribute。这个问题是 Swagger 给了我一个无聊的请求 URL 比如:

/v1/areas/{areaName}/series?areaName=testarea &from=20151201

我希望它以与我使用时相同的方式显示 @PathVariable:

/v1/areas/testarea/series?from=20151201

我试过在请求类中使用 @ApiParam 甚至尝试 hidden=true 以在控制器中保留 @PathVariable 并仅隐藏请求类中的 @ApiParam不要在 Swagger UI 中获得 areaName 的副本,但隐藏似乎不起作用。我正在使用 Swagger/SwaggerUI 版本 2.3.0.. 有什么想法吗?

请求类:

public class AreaSeriesRequest {

@ApiParam(value = "Area selector, wich area to get series from.", required = true)
@EnergyAreas
private String areaName;

public String getAreaName() {
    return AreaName;
}

public void setAreaName(String areaName) {
    this.areaName = areaName;
}

控制器:

@RequestMapping(value = "/{areaName}/series", method = GET, produces = json)
@ResponseStatus(HttpStatus.OK)
    public Page<GroupSeriesDto> getAreaSeriesPaginated(
            //@PathVariable String areaName,
            @Valid @ModelAttribute AreaSeriesRequest seriesRequest, BindingResult seriesResult,
            @ModelAttribute PagingRequest pagingRequest,
            Principal currentUser) {

所以我解决这个问题的方法是仍然使用 @PathVariable 但不是 @Valid @ModelAttribute 在 areaName 上我为这个参数做了一个单独的验证器。

public class AreaValidator implements Validator {

private static final List<String> types = Arrays.asList(
        "ALL",
        "XX1",
        "XX2",
        "XX3",
        "XX4"
);

@Override
public boolean supports(Class<?> clazz) {
    return String.class.equals(clazz);
}

@Override
public void validate(Object target, Errors e) {
    String value = (String) target;

    if (value == null || !types.contains(value.toUpperCase())) {
        e.reject(String.format("Area '%s' does not exist", value));
    }
}

然后在控制器中使用它,如:

new AreaValidator().validate(areaName, seriesResult);

if (seriesResult.hasErrors())
throw new AreaNotFoundException(areaName);