Java 如何配置Swagger UI、Jersey和文件上传?

Java 如何配置Swagger UI、Jersey和文件上传?,java,rest,jersey,swagger,swagger-ui,Java,Rest,Jersey,Swagger,Swagger Ui,我有一个Jersey服务,其文件上载方法如下(简化): 因此,Swagger UI为FormDataCodePart参数生成一个文件选择器字段和一个额外的文本字段: 因此,当我选择一个文件并在Swagger UI中提交表单时,我最终读取的是InputStream中文本字段的内容,而不是上传文件的内容。如果我将textfield留空,就会得到文件名 如何指示Swagger忽略FormDataCodePart参数 或者,作为一种解决方法,在没有FormDataCodePart对象的情况下,如何获取

我有一个Jersey服务,其文件上载方法如下(简化):

因此,Swagger UI为FormDataCodePart参数生成一个文件选择器字段和一个额外的文本字段:

因此,当我选择一个文件并在Swagger UI中提交表单时,我最终读取的是InputStream中文本字段的内容,而不是上传文件的内容。如果我将textfield留空,就会得到文件名

如何指示Swagger忽略FormDataCodePart参数

或者,作为一种解决方法,在没有FormDataCodePart对象的情况下,如何获取上载文件的媒体类型


我使用Jersey 2.7和swagger-Jersey 2-jaxrs_2.10版本1.3.4。

为Jersey创建一个swagger过滤器,然后将该参数标记为内部或其他要过滤的字符串。此示例中也显示了这一点:

您的服务方法将具有此参数注释

@ApiParam(access = "internal") @FormDataParam("file") FormDataBodyPart body,
您的筛选器将按如下方式查找它:

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.paramAccess().isDefined() && parameter.paramAccess().get().equals("internal")))
        return false;
    else
        return true;
}
public boolean isParamAllowed(参数、操作、api描述api、,
映射参数、映射cookie、映射头){
if((parameter.paramAccess().isDefined()&¶meter.paramAccess().get().equals(“内部”))
返回false;
其他的
返回true;
}
为jersey注册您的swagger过滤器,然后它将不会返回该字段,并且swagger ui将不会显示该字段,这将解决您的上载问题

<init-param>
      <param-name>swagger.filter</param-name>
      <param-value>your.company.package.ApiAuthorizationFilterImpl</param-value>
    </init-param>

招摇过市
your.company.package.ApiAuthorizationFilterImpl

不清楚这是什么时候添加到Jersey的,但在多部分部分部分末尾的一条注释中说“@FormDataParam注释也可以用于字段”。果然,您可以做到这一点:

@FormDataParam(value="file") FormDataContentDisposition fileDisposition;
@FormDataParam("fileBodyPart") FormDataBodyPart body;

@Path("/v1/source")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.APPLICATION_JSON})
@ApiOperation(
        value = "Create a new Source from an uploaded file.",
        response = Source.class
        )
public Response makeSource(
        @FormDataParam(value="file") InputStream inputStream
        )
{
    logger.info(fileDisposition.toString());
    return makeSourceRaw(inputStream, fileDisposition.getFileName());
}
这提供了FormDataContentDisposition,但使其“不可见”以招摇过市

更新:如果定义了其他不采用FormDataContentDisposition的资源(@Path annotations),则此操作无效。如果有,Jersey将在运行时失败,因为它无法填充fileDisposition字段

如果您使用最新版本的Swagger将参数简单地标记为隐藏,那么这是一个更好的解决方案

@FormDataParam("fileBodyPart") FormDataBodyPart body;

@Path("/v1/source")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.APPLICATION_JSON})
@ApiOperation(
        value = "Create a new Source from an uploaded file.",
        response = Source.class
        )
public Response makeSource(
        @FormDataParam(value="file") InputStream inputStream,
        @ApiParam(hidden=true) @FormDataParam(value="file") FormDataContentDisposition fileDisposition;

        )
{
    logger.info(fileDisposition.toString());
    return makeSourceRaw(inputStream, fileDisposition.getFileName());
}

谢谢,成功了。我真的不想在我的代码中为swagger添加更多的依赖项,但它解决了这个问题,所以我满足了。Hi@Pierrehhenry我也在使用maven插件生成swagger json,但它将java.io.InputStream显示为一种类型,而不是java.io.File。你有没有犯过这个错误?对不起,这是很久以前的事了,我记不得了。我想你最好还是问一个新问题。有人知道这个文件上传是否可以通过jersey1实现吗?(我使用的是1.19)不知何故,即使我有多部分/表单数据,我也无法让文件上传工作。此外,在swagger的最新版本中,参数中显示为“body”而不是“file”,注释@ApiParam(hidden=true)应替换为@Parameter(hidden=true)。
@FormDataParam(value="file") FormDataContentDisposition fileDisposition;
@FormDataParam("fileBodyPart") FormDataBodyPart body;

@Path("/v1/source")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.APPLICATION_JSON})
@ApiOperation(
        value = "Create a new Source from an uploaded file.",
        response = Source.class
        )
public Response makeSource(
        @FormDataParam(value="file") InputStream inputStream
        )
{
    logger.info(fileDisposition.toString());
    return makeSourceRaw(inputStream, fileDisposition.getFileName());
}
@FormDataParam("fileBodyPart") FormDataBodyPart body;

@Path("/v1/source")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.APPLICATION_JSON})
@ApiOperation(
        value = "Create a new Source from an uploaded file.",
        response = Source.class
        )
public Response makeSource(
        @FormDataParam(value="file") InputStream inputStream,
        @ApiParam(hidden=true) @FormDataParam(value="file") FormDataContentDisposition fileDisposition;

        )
{
    logger.info(fileDisposition.toString());
    return makeSourceRaw(inputStream, fileDisposition.getFileName());
}