首页 > 其他分享 >Swagger3 (OpenAPI3)自定义参数对象渲染设置ModelConverter

Swagger3 (OpenAPI3)自定义参数对象渲染设置ModelConverter

时间:2023-08-29 14:34:07浏览次数:57  
标签:OpenAPI3 return 自定义 private Swagger3 public GwPageRequest 参数 class

Swagger2设置方法

以SpringDataJPA里的分页参数Pageable为例, 在使用Swagger2的时候, 可以通过自定义AlternateTypeRule, 修改参数对象的参数渲染; 如下

/**
 * 分页参数实体类参数转换, 让swagger显示正常的传参
 * 
 * @param resolver
 * @return
 */
@Bean
public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) {
    return new AlternateTypeRuleConvention() {
        @Override
        public int getOrder() {
            return Ordered.LOWEST_PRECEDENCE;
        }

        @Override
        public List<AlternateTypeRule> rules() {
            List<AlternateTypeRule> altRules = new ArrayList<>();
            altRules.add(newRule(resolver.resolve(Pageable.class), resolver.resolve(PageableAlternate.class)));
            altRules.add(newRule(resolver.resolve(PageRequest.class), resolver.resolve(PageableAlternate.class)));
            return altRules;
        }
    };
}

/**
 * Pageable的替代别名类
 */
@Data
@ApiModel
public class PageableAlternate {
    @ApiModelProperty(value = "第几页, page从0开始计数")
    private Integer page;

    @ApiModelProperty(value = "每页数据数量")
    private Integer size;

    @ApiModelProperty(value = "按属性排序, 格式: 属性(asc|desc)。多字段排序传参eg: ?sort=id,asc&sort=name,desc")
    private List<String> sort;
}

Swagger3设置方法

在swagger3里, 已经内置了SpringDataJPA的Pageable参数的转换器, 无需自行添加了; 这里提供下如何自定义参数转换器:

  1. 自定义转换器实现io.swagger.v3.core.converter.ModelConverter接口

这里有一个GwPageRequest了封装了分页查询条件

/**
 * 分页请求参数
 * 
 * @author 吕晓飞
 * @date 2023-06-27 15:21
 * @version 1.0
 */
public class GwPageRequest implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 当前页码, 从1开始
	 */
	@Getter
	@Setter
	private int pageNumber = 1;

	/**
	 * 每页大小, 默认10条
	 */
	@Getter
	@Setter
	private int pageSize = 10;

	/**
	 * 排序信息
	 */
	@Getter
	@Setter
	private List<GwSort> sort;

	/**
	 * 搜索信息
	 */
	@Getter
	@Setter
	private GwSearch search;

}
/**
 * GwPageRequest的替代别名类
 *
 * @author 吕晓飞
 * @date 2023-06-27 15:21
 * @version 1.0
 */
@Data
@Schema(description = "分页参数")
static class GwPageRequestAlternate {

    @Schema(description = "当前页码, 从1开始", defaultValue = "1")
    private int pageNumber = 1;

    @Schema(description = "每页大小, 默认10条", defaultValue = "10")
    private int pageSize = 10;

    @Schema(description = "按属性排序. 单字段排序eg: ?sort=id|asc 多字段排序eg: ?sort=id|asc,name|desc", nullable = true)
    private List<String> sort;

    @Schema(description = "搜索信息. eg: ?search=field|keyword", nullable = true)
    private String search;
}

/**
 * GwPageRequest模型参数转换
 */
static class GwPageRequestConverter implements ModelConverter {

    /**
     * 待转换的参数类型全限定名
     */
    private static final String TO_BE_REPLACE = "cn.rsmis.gpm.core.page.GwPageRequest";

    /**
     * 替换后的类型
     */
    private static final AnnotatedType REPLACEED_TYPE = new AnnotatedType(GwPageRequestAlternate.class).resolveAsRef(true);

    /**
     * Spring doc 对象映射器提供者的类型。
     */
    private final ObjectMapperProvider springDocObjectMapper;

    /**
     * 构造方法: 实例化一个新的 GwPageRequest openApi 转换器
     *
     * @param springDocObjectMapper the spring doc object mapper
     */
    public GwPageRequestConverter(ObjectMapperProvider springDocObjectMapper) {
        this.springDocObjectMapper = springDocObjectMapper;
    }

    @Override
    public io.swagger.v3.oas.models.media.Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
        JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType());
        if (javaType != null) {
            Class<?> cls = javaType.getRawClass();
            if (TO_BE_REPLACE.equals(cls.getCanonicalName())) {
                if (!type.isSchemaProperty()) {
                    type = REPLACEED_TYPE;
                } else {
                    type.name(cls.getSimpleName() + StringUtils.capitalize(type.getParent().getType()));
                }
            }
        }
        return (chain.hasNext()) ? chain.next().resolve(type, context, chain) : null;
    }
}
  1. 注册自定义参数的Converter
/**
 * 注册自定义参数的Converter
 *
 * @param objectMapperProvider
 * @return
 */
@Bean
@Lazy(false)
GwPageRequestConverter pageableOpenAPIConverter(ObjectMapperProvider objectMapperProvider) {
    // 将 参数对象 替换为目标类
    SpringDocUtils.getConfig().replaceParameterObjectWithClass(GwPageRequest.class, GwPageRequestAlternate.class);
    return new GwPageRequestConverter(objectMapperProvider);
}
  1. 在controller方法形参声明
/**
 * 分页查询
 *
 * @param pageRequest 分页条件
 * @return 分页对象
 */
@Operation(summary = "分页查询")
@GetMapping("/page")
public ResultBean<GwPageResult<JobEntity>> page(@ParameterObject GwPageRequest pageRequest) {
    return ResultBean.success(iJobService.getPage(pageRequest));
}

注意如果使用了Knife4j等增强框架, 需要添加 @ParameterObject注解, 否则无法正常渲染详见https://gitee.com/xiaoym/knife4j/issues/I6HDXO
最终效果
image.png

标签:OpenAPI3,return,自定义,private,Swagger3,public,GwPageRequest,参数,class
From: https://www.cnblogs.com/iminifly/p/17664664.html

相关文章

  • C# 在datatable中添加自定义字段
    DataTabledt=newDataTable();sql.Append("SELECTafromb");dt=SqlHelper.GetDataTable(sql.ToString());sql=newStringBuilder();sql.Append("SELECTcfromd");varjcdt=SqlHelper.GetDataTable(sql.ToString());......
  • RTSP/Onvif协议安防视频平台EasyNVR录像模式自定义操作
    TSINGSEE青犀视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif流媒体协议接入,并能对接入的视频流进行处理与多端分发,包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。在智慧安防等视频监控场景中,EasyNVR可提供视频实时监控直播、云端录像、云存储、录像检索与回看、告......
  • webman:自定义配置文件(v1.5.7)
    一,官方文档地址:https://www.workerman.net/doc/webman/config.html二,代码:1,.env:GOODS_IMAGE_DIR=/var/www/html/goodsImageGOODS_IMAGE_HOST=http://192.168.219.62,config/images.php12345<?phpreturn[   "goodsImageDir"=>getenv(......
  • Kubernetes编程—— 如何操作自定义资源
    如何操作自定义资源client-go为每种kubernetes内置资源提供对应的clientset和informer。那如果我们要监听和操作自定义资源对象,应该如何做呢?这里我们有两种方式:我理解意思是说:1、使用client-go提供的dynamicClient来操作自定义操作资源对象,当......
  • VMware Tools 12.2.6 - 修复 SRM 无法对 Windows 虚拟机执行 IP 自定义的问题
    VMwareTools12.2.6请访问原文链接:https://sysin.org/blog/vmware-tools-12/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org简介VMwareTools中包含一系列服务和组件,可在各种VMware产品中实现多种功能,从而使用户能够更好地管理客户机操作系统,以及与客户机操作系......
  • 成品直播源码推荐,android自定义显示图片+文字
    成品直播源码推荐,android自定义显示图片+文字 /** *@authorMartin-harry *@date2021/8/10 *@address *@Desc自定义toast */publicclassToastUtil{  /**   *显示文本+图片   *@paramcontext   *@parammessage   */  publicsta......
  • pycharm中自定义函数补全
    在PyCharm中,你可以通过以下步骤实现这一目标:打开PyCharm,点击顶部菜单的"File"(文件)->"Settings"(设置)。在弹出的窗口中,选择"Editor"(编辑器)->"LiveTemplates"(代码模板)。在左侧的列表中,选择"Python"或者你希望的分类,然后点击右侧的"+"按钮,添加一个新的代码模板。......
  • 在 PHP 中,原生并没有提供内置的定时器机制,定时触发的守护进程,其中一个常见的方式是使
    <?phpclassTimerDaemon{private$logfile;private$fp;private$triggerInterval;//触发间隔,以秒为单位private$lastTriggerTime;publicfunction__construct($logfile,$triggerInterval){$this->logfile=$logfile;......
  • js自定义事件
    新建js新建自定义事件方式有两种:1.newEvent('myEvent',initEvent)2.newCustomEvent('myEvent',initEvent)//newCustomEvent('myEvent',{detail:{name:'yejingxiao'}})相同点简单的自定义事件Event,CustomEvent都可以用,且第二个参数都是可选非必填参数,用以配置常见......
  • WPF-封装自定义雷达图控件
     源码地址:https://gitee.com/LiuShuiRuoBing/code_blog雷达图用于表示不同内容的占比关系,在项目中有广泛的应用,但是目前未曾有封装良好的雷达图控件,鉴于最近项目的使用,于是想要封装一个通用的雷达图控件,便于日后的扩展使用。首先雷达图的绘制大概分为雷达图的图层、......