Для этого есть несколько шагов.
Прежде всего, нам нужен правильный objectMapper, чтобы MonetaryAmount
отображался на нужный объект с двумя полями currency
и rate
. Для этого нам нужно добавить пользовательский модуль для objectMapper в Springfox.
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.zalando.jackson.datatype.money.MoneyModule;
import springfox.documentation.schema.configuration.ObjectMapperConfigured;
@Component
public class SwaggerJacksonModule implements ApplicationListener<ObjectMapperConfigured> {
@Override
public void onApplicationEvent(ObjectMapperConfigured event) {
event.getObjectMapper().registerModule(new MoneyModule());
}
}
Объяснение: Мы добавляем слушателя к событию ObjectMapperConfigured
в Springfox, и всякий раз, когда событие запускается, мы просто получаем преобразователь и регистрируем наш модуль. Я использую библиотеку данных типа Джексона Заландо, чтобы не писать свою собственную.
Следующим шагом будет работа над фактическим представлением Swagger. Давайте создадим наш собственный объект представления MonetaryWrapper
, который мы будем использовать для замены MonetaryAmount
.
public class MonetaryWrapper {
private BigDecimal amount;
private String currency;
// getters and setters (getters are important)
}
Для правильного представления одиночного объекта достаточно добавить .directModelSubstitute(MonetaryAmount.class, MonetaryWrapper.class)
к Docket
объекту.
НО Это не так просто для коллекций. например, список в этом случае. Нам нужно добавить объект Special AlternateTypeRule
в объект Docket
, чтобы списки отображались правильно.
Подробнее об этой теме в документации Springfox
Примерно так:
TypeResolver resolver = new TypeResolver();
AlternateTypeRule monetaryAmountListRule =
newRule(resolver.resolve(List.class, MonetaryAmount.class),
resolver.resolve(List.class, MonetaryWrapper.class))
И, наконец, наш Docket
боб будет выглядеть примерно так:
@Bean
public Docket productApi() {
TypeResolver resolver = new TypeResolver();
AlternateTypeRule monetaryAmountListRule =
newRule(resolver.resolve(List.class, MonetaryAmount.class),
resolver.resolve(List.class, MonetaryWrapper.class));
return new Docket(DocumentationType.SWAGGER_2)
.alternateTypeRules(monetaryAmountListRule)
.directModelSubstitute(MonetaryAmount.class, MonetaryWrapper.class)
.select().apis(RequestHandlerSelectors.basePackage("com.swagger.test"))
.paths(PathSelectors.regex("/public.*")).build();
}
И некоторые демонстрационные скриншоты здесь:
Демонстрация при выполнении запроса:
Демо просто для описание объекта :