当前位置: 首页 > 知识库问答 >
问题:

OpenAPI规范说“应用程序/x-ww-form-urlencoded”,但生成的Spring boot需要多部分/form-data或多部分/混合流

杨无尘
2023-03-14

我试图使用现有Python演示中的OpenAPI规范来创建Java中的类似演示,并使用了带有OpenAPI生成器maven插件的“spring”生成器和以下配置选项:

                                <!-- generates single interface to implement -->
                                <useTags>true</useTags>

                                <withXml>true</withXml>
                                <title>${project.artifactId}</title>

                                <performBeanValidation>true</performBeanValidation>
                                <useBeanValidation>true</useBeanValidation>
                                <useOptional>true</useOptional>
                                <useSpringController>false</useSpringController>

                                <returnSuccessCode>false</returnSuccessCode>

                                <useAbstractionForFiles>true</useAbstractionForFiles>

                                <!-- Our own delegates can be autowired into the generated sources -->
                                <delegatePattern>true</delegatePattern>

下面是YAML片段:

post:
  description: Add products to shopping cart.
  operationId: api.cart.add_product

  requestBody:
    required: true
    content:
      'application/x-www-form-urlencoded':
        schema:
          type: object
          properties:
            quantity:
              type: integer
              example: 1
            product_code:
              type: string
              example: elephant
          required:
            - quantity
            - product_code
        examples:
          add_an_elephant:
            summary: How to add a single elephant to the shopping cart
            value:
              product_code: elephant
              quantity: 1
  
  responses:
    '204':
      description: Product added to cart.
    '400':
      description: Cannot add product to cart.
    '422':
      description: Unknown product code.

使用一点额外的胶水,让Spring自动连接请求变量,这将编译并启动。现在我的问题是,正如OpenAPI文件中所说,swagger页面生成了一个应用程序/x-www-form-urlencoded请求,但Tomcat在尝试调用时失败了:

    @RequestMapping(
        method = RequestMethod.POST,
        value = "/cart/add",
        consumes = { "application/x-www-form-urlencoded" }
    )
    default ResponseEntity<Void> apiCartAddProduct(
        @Parameter(name = "quantity", description = "", required = true, schema = @Schema(description = "")) @Valid @RequestPart(value = "quantity", required = true) Integer quantity,
        @Parameter(name = "product_code", description = "", required = true, schema = @Schema(description = "")) @Valid @RequestPart(value = "product_code", required = true) String productCode
    ) {
        return getDelegate().apiCartAddProduct(quantity, productCode);
    }

然后调用

    @Override
    public ResponseEntity<Void> apiCartAddProduct(Integer quantity, String productCode) {
        var product = products.stream().filter(p -> p.getCode().equals(productCode)).findFirst().get();
        CartEntry price = new CartEntry().product(product).price(product.getPrice()).quantity(quantity).price(product.getPrice() * quantity);
        cart.add(price);
        return new ResponseEntity<Void>((Void) null, HttpStatus.OK);
    }

除此之外:


org.apache.tomcat.util.http.fileupload.impl.InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is application/x-www-form-urlencoded
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.init(FileItemIteratorImpl.java:151) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.getMultiPartStream(FileItemIteratorImpl.java:205) ~[tomcat-embed-core-9.0.56.jar:9.0.56]

我的理解是,OpenAPI生成器应该生成可以接受YAML文件中声明的类型的代码,但可能有很多原因导致它不能接受。

我的问题是,我不明白为什么这是一个问题,以及它的原因。出了什么问题,我该如何解决?如果有可能避免更改openapi yaml文件,我宁愿这样做。

编辑:在Tomcat看到的apiCartAddProduct的定义中,似乎通过实验将@RequestPart更改为@RequestParam使其工作。由于这是更改自动生成的代码,我正在寻找更好的解决方案。建议?

共有1个答案

韦澄邈
2023-03-14

看来这是故意闯入的https://github.com/OpenAPITools/openapi-generator/commit/a0eb149df5b722bfd43cf3587399c118850af76c(4.3版),类似于https://github.com/OpenAPITools/openapi-generator/issues/7794,然后固定在https://github.com/OpenAPITools/openapi-generator/commit/33b89148e562fc2d5acf60a56719c46ec4f631e8 (2022-02-27)

这意味着我使用的5.4.0版本并不是固定的,但6.0.0-beta版本是固定的。

升级到测试版修复了这个问题。

 类似资料:
  • 本文向大家介绍说说form-data、x-www-form-urlencoded、raw、binary的区别是什么?相关面试题,主要包含被问及说说form-data、x-www-form-urlencoded、raw、binary的区别是什么?时的应答技巧和注意事项,需要的朋友参考一下 同 发送请求的方式 异 1.multipart/form-data 其请求内容格式为Content-Type:

  • 我的要求很简单。 响应是xml格式的。 我尝试了很多地方的例子,但似乎没有任何效果。它返回401 Unauthorized,如果请求的格式不正确,目标API就会抛出这个错误。

  • 我正在使用最新版本的openapi-用户界面1.6.7,我无法使文件上传endpoint工作。这是我对参数的配置: 当我在生成的招摇过市UI中使用“试用”按钮时,会出现415个不支持的媒体类型错误。请求头的内容类型为: 我认为这就是错误的来源。从OpenApi生成的json如下所示: 我缺少什么来发送表单数据内容类型的正确请求?

  • 我有一个基于jersey的web服务,它生成一个“多部分/混合”响应,如下所示:该方法读取一个文件,并应以八位字节格式返回它。 我的问题是:如何确保响应为八位字节流类型?我知道我也可以将上述方法注释为: 但是我特别要求在发送八位流格式的文件时将响应内容类型设置为“多部分/混合”。 上面的方法做到了吗?我的假设是有,但我没有具体的理由。 提前谢谢你!

  • 但这是错误的,因为值广告是字符串而不是数组。

  • 我有一些参数,我想POST格式编码到我的服务器: 我发送的请求(目前没有参数)如下 如何在请求中包含表单编码参数?