Swagger 时间戳(Timestamp)或者其他类型显示异常问题

Swagger 如果查询参数类型是List或者Timestamp会不断的被展开显示
原因是因为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)

posted @ 2022-03-24 17:49  哦哈呦  阅读(371)  评论(0)    收藏  举报