OpenApi Spec说“应用程序/x-ww-form-urlenCoded”但是生成的弹簧靴期望多部分/form-data或多部分/混合流

发布于 2025-01-23 08:16:21 字数 4338 浏览 0 评论 0 原文

我正在尝试使用现有Python演示的OpenAPI规格在Java中创建类似的演示,并使用OpenAPI-Generator-Maven-Plugin和以下配置使用了“ 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 Snippet:

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 AutoWire request变量此编译并启动。现在我的问题是Swagger页面生成 application/x-www-form-urlencoded 请求,如OpenAPI文件中所述,但是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 Generator应该生成可以接受YAML文件中所述类型的代码,但是可能有很多原因。

我的问题是我不明白为什么这是一个问题,以及导致它的原因。 有什么问题,我该如何修复它?


编辑:看来,在Tomcat看到的 apicartaddproduct 的定义中,实验性地将 @requestPart @requestparam @requestparam 使其正常工作。由于这正在更改自动生成的代码,因此我正在寻找更好的解决方案。建议?

I am trying to use an OpenAPI spec from an existing Python demo to create a similar demo in Java, and have used the "spring" generator with openapi-generator-maven-plugin and the following configOptions:

                                <!-- 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>

and this YAML snippet:

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.

With a little extra glue to let Spring autowire the request variable this compiles and starts. Now my problem is that the swagger page generates a application/x-www-form-urlencoded request as said in the OpenAPI file, but Tomcat fails when trying to invoke:

    @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);
    }

which then invokes

    @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);
    }

with this exception:


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]

My understanding is that OpenAPI generator should generate code that can accept the type stated in the YAML file, but there might be many reasons for it not to.

My problem is that I do not understand why this is a problem in the first place, and what causes it. What is wrong and how can I fix it? If it is at all possible to avoid changing the openapi yaml file I'd prefer that.


EDIT: It appears that experimentally changing @RequestPart to @RequestParam in the definition of apiCartAddProduct that Tomcat sees, makes it work. As this is changing automatically generated code I'm looking for a better solution. Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

煞人兵器 2025-01-30 08:16:21

It appears that this was deliberately broken in https://github.com/OpenAPITools/openapi-generator/commit/a0eb149df5b722bfd43cf3587399c118850af76c (version 4.3), reported several times like in https://github.com/OpenAPITools/openapi-generator/issues/7794, and then fixed in https://github.com/OpenAPITools/openapi-generator/commit/33b89148e562fc2d5acf60a56719c46ec4f631e8 (2022-02-27)

This means that version 5.4.0 that I was using wasn't fixed, but 6.0.0-beta was.

An upgrade to the beta version fixed the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文