【问题标题】:How can I set Swagger to ignore @Suspended AsyncResponse in @Asynchronous jax-rs bean methods?如何设置 Swagger 以忽略 @Asynchronous jax-rs bean 方法中的 @Suspended AsyncResponse?
【发布时间】:2014-03-21 14:15:54
【问题描述】:

Swagger-Core 似乎将 @Suspended final AsyncResponse asyncResponse 成员解释为请求正文参数。这显然不是故意的,也不是事实。

我想告诉 swagger-core 忽略此参数并将其从 api-docs 中排除。有什么想法吗?

这是我的代码的样子:

@Stateless
@Path("/coffee")
@Api(value = "/coffee", description = "The coffee service.")
public class CoffeeService
{
    @Inject
    Event<CoffeeRequest> coffeeRequestListeners;

    @GET
    @ApiOperation(value = "Get Coffee.", notes = "Get tasty coffee.")
    @ApiResponses({
            @ApiResponse(code = 200, message = "OK"),
            @ApiResponse(code = 404, message = "Beans not found."),
            @ApiResponse(code = 500, message = "Something exceptional happend.")})
    @Produces("application/json")
    @Asynchronous
    public void makeCoffee( @Suspended final AsyncResponse asyncResponse,

                             @ApiParam(value = "The coffee type.", required = true)
                             @QueryParam("type")
                             String type)
    {
        coffeeRequestListeners.fire(new CoffeeRequest(type, asyncResponse));
    }
}

更新:基于答案的解决方案

public class InternalSwaggerFilter implements SwaggerSpecFilter
{
    @Override
    public boolean isOperationAllowed(Operation operation, ApiDescription apiDescription, Map<String, List<String>> stringListMap, Map<String, String> stringStringMap, Map<String, List<String>> stringListMap2) {
        return true;
    }

    @Override
    public boolean isParamAllowed(Parameter parameter, Operation operation, ApiDescription apiDescription, Map<String, List<String>> stringListMap, Map<String, String> stringStringMap, Map<String, List<String>> stringListMap2) {
        if( parameter.paramAccess().isDefined() && parameter.paramAccess().get().equals("internal") )
            return false;
        return true;
    }
}

FilterFactory.setFilter(new InternalSwaggerFilter());

修改示例代码片段

...
@Asynchronous
public void makeCoffee( @Suspended @ApiParam(access = "internal") final AsyncResponse asyncResponse,...)
...

【问题讨论】:

    标签: ejb jax-rs swagger


    【解决方案1】:

    快进到 2016 年,swagger-springmvc 被 springfox 取代(文档可在 here 获得)。在 springfox 中可以忽略参数,但由于某种原因没有记录:

    备选方案 1:全局忽略 Docket 配置中带有 .ignoredParameterTypes(...) 的类型或注释类型:

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
            .host(reverseProxyHost)
            .useDefaultResponseMessages(false)
            .directModelSubstitute(OffsetDateTime.class, String.class)
            .directModelSubstitute(Duration.class, String.class)
            .directModelSubstitute(LocalDate.class, String.class)
            .forCodeGeneration(true)
            .globalResponseMessage(RequestMethod.GET, newArrayList(
                new ResponseMessageBuilder()
                    .code(200).message("Success").build()
                )
            .apiInfo(myApiInfo())
            .ignoredParameterTypes(AuthenticationPrincipal.class, Predicate.class, PathVariable.class)
            .select()
                .apis(withClassAnnotation(Api.class))
                .paths(any())
            .build();
    }
    

    Alternativ 2:使用@ApiIgnore-annotation 忽略方法中的单个参数:

    @ApiOperation(value = "User details")
    @RequestMapping(value = "/api/user", method = GET, produces = APPLICATION_JSON_UTF8_VALUE)
    public MyUser getUser(@ApiIgnore @AuthenticationPrincipal MyUser user) {
        ...
    }
    

    【讨论】:

    • 这个答案是 Spring 特定的。
    【解决方案2】:

    另一种方法可能是这样做。

    @Bean
    public SwaggerSpringMvcPlugin mvPluginOverride() {
        SwaggerSpringMvcPlugin swaggerSpringMvcPlugin = new SwaggerSpringMvcPlugin(this.springSwaggerConfig).apiInfo(apiInfo());
        swaggerSpringMvcPlugin.ignoredParameterTypes(PagedResourcesAssembler.class, Pageable.class);
        return swaggerSpringMvcPlugin;
    }
    

    【讨论】:

      【解决方案3】:

      我使用与您相同的技术解决了这个问题,但使用了不同的方法。我没有将其标记为内部,而是忽略了所有类型为 AsyncResponse 的参数,这样我就不需要更新所有方法中的代码来添加访问修饰符。

      public class CustomSwaggerSpecFilter implements SwaggerSpecFilter {
          @Override
          public boolean isOperationAllowed(Operation operation, ApiDescription api, Map<String, List<String>> params, Map<String, String> cookies,
                  Map<String, List<String>> headers) {
              return true;
          }
      
          @Override
          public boolean isParamAllowed(Parameter parameter, Operation operation, ApiDescription api, Map<String, List<String>> params,
                  Map<String, String> cookies, Map<String, List<String>> headers) {
              if(parameter.dataType().equals("AsyncResponse")) { // ignoring AsyncResponse parameters
                  return false;
              }
      
              return true;
          }
      }
      

      这对我来说效果更好。

      【讨论】:

      • 您使用哪个版本。对我来说没有这样的方法dataType()?
      • 对不起,这是很久以前的事了,不记得是什么版本了,不再使用那个代码库。我认为从那时起,Swagger API 发生了很大变化。
      【解决方案4】:

      我认为您必须使用过滤器。 这是一个例子https://github.com/wordnik/swagger-core/issues/269

      也可以用 java 编码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-08
        • 2012-12-29
        • 2017-11-22
        • 2013-12-07
        • 2015-02-07
        • 1970-01-01
        相关资源
        最近更新 更多