Swagger 时间戳(Timestamp)或者其他类型显示异常问题
Swagger 如果查询参数类型是List
原因是因为Swagger的基本类型只有
Short.TYPE, "int"
Integer.TYPE, "int"
Double.TYPE, "double"
Float.TYPE, "float"
Byte.TYPE, "byte"
Boolean.TYPE, "boolean"
Character.TYPE, "string"
Date.class, "date-time"
java.sql.Date.class, "date"
String.class, "string"
Object.class, "object"
Long.class, "long"
Integer.class, "int"
Short.class, "int"
Double.class, "double"
Float.class, "float"
Boolean.class, "boolean"
Byte.class, "byte"
BigDecimal.class, "bigdecimal"
BigInteger.class, "biginteger"
Currency.class, "string"
UUID.class, "uuid"
MultipartFile.class, "__file"
解决办法:如果不是以上几种类型会一直展开,所以需要把Timestamp类型映射为Date类型的规则,修改方式:
@Bean
public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) {
return new AlternateTypeRuleConvention() {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public List<AlternateTypeRule> rules() {
Type originalType = new TypeReference<List<Timestamp>>() {}.getType();
Type alternateType = new TypeReference<List<Date>>() {}.getType();
return newArrayList(
newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class)),
newRule(resolver.resolve(Timestamp.class), resolver.resolve(Date.class)),
newRule(originalType, alternateType)
);
}
};
}
源码位置参考:
springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander#expand (...) {
...
FluentIterable<ModelAttributeField> attributes =
allModelAttributes(
propertyLookupByGetter,
getters,
fieldsByName,
alternateTypeProvider);
...
// 遍历所有属性,不是基本类型会递归解析
for (ModelAttributeField each : collectionTypes) {
LOG.debug("Attempting to expand collection/array field: {}", each.getName());
ResolvedType itemType = collectionElementType(each.getFieldType());
if (Types.isBaseType(itemType) || enumTypeDeterminer.isEnum(itemType.getErasedType())) {
parameters.add(simpleFields(context.getParentName(), context, each));
} else {
ExpansionContext childContext = context.childContext(
nestedParentName(context.getParentName(), each),
itemType,
context.getOperationContext());
if (!context.hasSeenType(itemType)) {
parameters.addAll(expand(childContext));
}
}
}
}
public class AlternateTypeProvider {
private List<AlternateTypeRule> rules = Lists.newArrayList();
public AlternateTypeProvider(List<AlternateTypeRule> alternateTypeRules) {
this.rules.addAll(alternateTypeRules);
}
public ResolvedType alternateFor(ResolvedType type) {
Optional<AlternateTypeRule> matchingRule = FluentIterable.from(this.rules).firstMatch(this.thatAppliesTo(type));
return matchingRule.isPresent() ? ((AlternateTypeRule)matchingRule.get()).alternateFor(type) : type;
}
public void addRule(AlternateTypeRule rule) {
this.rules.add(rule);
}
private Predicate<AlternateTypeRule> thatAppliesTo(final ResolvedType type) {
return new Predicate<AlternateTypeRule>() {
public boolean apply(AlternateTypeRule input) {
return input.appliesTo(type);
}
};
}
}
这里不做源码解析,没啥好解析的,源码自己去探索,我只是做个问题记录。
另外这里涉及一个知识点是TypeReference,因为要创建AlternateTypeRule就要去创建Type
有大佬已经讲的很清除了,自己去了解:
Java中TypeReference用法说明_zhuzj12345的博客-CSDN博客_typereference
Class的 getSuperclass与getGenericSuperclass区别 - 茅坤宝骏氹 - 博客园 (cnblogs.com)

浙公网安备 33010602011771号