I have some problems trying to make my swagger UI return what I want.
The problem is that I want to display the areaName as a path parameter type NOT a query in the Swagger UI. I can do that by using @PathVariable String "areaName".
BUT I want to validate the areaname in a separate requestclass and now I'm trying to use @Valid @ModelAttribute instead. The problem with this is that Swagger gives me a boring request URL like:
/v1/areas/{areaName}/series?areaName=testarea&from=20151201
I want it to show the same way as when I'm using @PathVariable:
/v1/areas/testarea/series?from=20151201
I have tried playing around with the @ApiParam in the requestclass and even tried to hidden=true to keep a @PathVariable in the controller and just hide the @ApiParam in the requestclass to not get a duplicate of areaName in the Swagger UI but the hidden doesn't seem to work. I'm using Swagger/SwaggerUI version 2.3.0.. Any ideas?
Requestclass:
public class AreaSeriesRequest {
@ApiParam(value = "Area selector, which area to get series from.", required = true)
@EnergyAreas
private String areaName;
public String getAreaName() {
return AreaName;
}
public void setAreaName(String areaName) {
this.areaName = areaName;
}
Controller:
@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) {
So the way i worked around this was to still use the @PathVariable but instead of @Valid @ModelAttribute on the areaName i did a seperate validator for this parameter.
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));
}
}
And then used it in the controller like:
new AreaValidator().validate(areaName, seriesResult);
if (seriesResult.hasErrors())
throw new AreaNotFoundException(areaName);