修改接口参数名和在Swagger中的展示名

背景

我们有一个接口要支持后端排序,所以需要在请求对象里面增加两个参数:排序字段名、排序方式(asc、desc)。

正好基础jar包中有一个类可以直接拿来用。

@Data
public class OrderByItem {
    
    
	private String column;
    private String direction;
}

但是考虑到前端使用的是element框架,默认使用prop来定义排序字段,使用order来定义排序方式。

因此,考虑使用这两个属性来接受排序字段。但是仍然用OrderByItem这个类来接收参数。

为啥不重新定义一个类呢?

因为OrderByItem这个类还有配套的工具类,用来进行相关的转换。所以为了复用这个工具类,就有了这个奇葩需求——我要用OrderByItem这个类型来接受参数,但是这两个参数在Swagger中要展示成另外的名字,前端也需要用另外的名字来传参。

老实说,直接用columndirection没啥大问题。因此我们不去讨论这样做是否合理,姑且看如果我想实现类似的效果应该怎么处理。

JSON格式

如果OrderByItem作为JSON格式使用,那么就很简单了:

@Data
public class OrderByItem {
    
    
    @JsonProperty("prop")
	private String column;

    @JsonProperty("order")
    private String direction;
}

这里直接使用JsonProperty注解即可。

非JSON格式

如果不是JSON格式,事情会变得麻烦一点。

首先是要解决参数接收的问题,这里可以定义一个HandlerMethodArgumentResolver

public static class OrderItemHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    
    

        private static final String ORDER = "order";
        private static final String ORDER_DESC = "descending";
        private static final String ORDER_ASC = "ascending";
        private static final String PROP = "prop";

        @Override
        public boolean supportsParameter(MethodParameter parameter) {
    
    
            return OrderByItem.class.isAssignableFrom(parameter.getParameterType());
        }

        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
    
    

            String prop = webRequest.getParameter(PROP);
            if (StringUtils.isBlank(prop)) {
    
    
                return null;
            }

            String order = webRequest.getParameter(ORDER);
            // validate order

          	OrderByItem orderByItem = new OrderByItem();
			orderByItem.setColumn(prop);
		    orderByItem.setDirection(order);
			
            return orderByItem;
        }
    }

注册OrderItemHandlerMethodArgumentResolver:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    

    @Override
    public void addFormatters(FormatterRegistry registry) {
    
    
       registry.addConverter(new OrderItemHandlerMethodArgumentResolver());
    }
}

这里虽然解决了参数接收的问题,但是Swagger生成的文档参数名还是columndirection。我们需要改成proporder

由于OrderByItem是jar包中的类,无法修改源码,所以不能直接使用ApiModelProperty这个注解。

好在Swagger提供了一个“替身”功能,我们需要先定义一个替身类:

@Data
@ApiModel("排序")
public static class OrderRequest {
    
    

    @ApiModelProperty("字段名称")
    private String prop;

    @ApiModelProperty("排序方式:descending倒序,ascending:正序")
    private String order;
}

然后使用替身:

@Configuration
public class SwaggerConfig {
    
    

    private ApiInfo apiInfo() {
    
    
        return new ApiInfoBuilder()
                .title("test")
                .description("test")
                .version("1.0")
                .build();
    }

    @Bean
    public Docket api() {
    
    
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .directModelSubstitute(OrderByItem.class, OrderRequest.class);
    }
}

这样做,当Swagger显示OrderByItem类时,就会用OrderByItem代替。

猜你喜欢

转载自blog.csdn.net/qq_23365135/article/details/131726272