java之openapi springboot 服务器生成器是否有损坏的线程模型

lhb25 阅读:46 2023-08-09 13:37:52 评论:0

因此我们正在尝试使用 OpenAPI 生成器,但到目前为止我们得到了不同的结果。

重现步骤:

  1. 下载 openapi 生成器 jar:wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator/4.0.3/openapi-generator-4.0.3.jar
  2. 为宠物店示例生成 springboot 服务器:java -jar openapi-generator-cli-4.0.3.jar generate -g spring -i https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml

您最终会得到如下所示的 Controller 类:

package org.openapitools.api; 
 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.context.request.NativeWebRequest; 
import java.util.Optional; 
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2019-08-06T15:08:49.070+01:00[Europe/London]") 
 
@Controller 
@RequestMapping("${openapi.swaggerPetstore.base-path:/v1}") 
public class PetsApiController implements PetsApi { 
 
    private final NativeWebRequest request; 
 
    @org.springframework.beans.factory.annotation.Autowired 
    public PetsApiController(NativeWebRequest request) { 
        this.request = request; 
    } 
 
    @Override 
    public Optional<NativeWebRequest> getRequest() { 
        return Optional.ofNullable(request); 
    } 
 
} 
/** 
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (4.0.3). 
 * https://openapi-generator.tech 
 * Do not edit the class manually. 
 */ 
package org.openapitools.api; 
 
import org.openapitools.model.Error; 
import org.openapitools.model.Pet; 
import io.swagger.annotations.*; 
import org.springframework.http.HttpStatus; 
import org.springframework.http.MediaType; 
import org.springframework.http.ResponseEntity; 
import org.springframework.validation.annotation.Validated; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RequestHeader; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RequestPart; 
import org.springframework.web.context.request.NativeWebRequest; 
import org.springframework.web.multipart.MultipartFile; 
 
import javax.validation.Valid; 
import javax.validation.constraints.*; 
import java.util.List; 
import java.util.Map; 
import java.util.Optional; 
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2019-08-06T15:08:49.070+01:00[Europe/London]") 
 
@Validated 
@Api(value = "pets", description = "the pets API") 
public interface PetsApi { 
 
    default Optional<NativeWebRequest> getRequest() { 
        return Optional.empty(); 
    } 
 
    @ApiOperation(value = "Create a pet", nickname = "createPets", notes = "", tags={ "pets", }) 
    @ApiResponses(value = {  
        @ApiResponse(code = 201, message = "Null response"), 
        @ApiResponse(code = 200, message = "unexpected error", response = Error.class) }) 
    @RequestMapping(value = "/pets", 
        produces = { "application/json" },  
        method = RequestMethod.POST) 
    default ResponseEntity<Void> createPets() { 
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); 
 
    } 
 
 
    @ApiOperation(value = "List all pets", nickname = "listPets", notes = "", response = Pet.class, responseContainer = "List", tags={ "pets", }) 
    @ApiResponses(value = {  
        @ApiResponse(code = 200, message = "A paged array of pets", response = Pet.class, responseContainer = "List"), 
        @ApiResponse(code = 200, message = "unexpected error", response = Error.class) }) 
    @RequestMapping(value = "/pets", 
        produces = { "application/json" },  
        method = RequestMethod.GET) 
    default ResponseEntity<List<Pet>> listPets(@ApiParam(value = "How many items to return at one time (max 100)") @Valid @RequestParam(value = "limit", required = false) Integer limit) { 
        getRequest().ifPresent(request -> { 
            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { 
                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { 
                    ApiUtil.setExampleResponse(request, "application/json", "null"); 
                    break; 
                } 
            } 
        }); 
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); 
 
    } 
 
 
    @ApiOperation(value = "Info for a specific pet", nickname = "showPetById", notes = "", response = Pet.class, tags={ "pets", }) 
    @ApiResponses(value = {  
        @ApiResponse(code = 200, message = "Expected response to a valid request", response = Pet.class), 
        @ApiResponse(code = 200, message = "unexpected error", response = Error.class) }) 
    @RequestMapping(value = "/pets/{petId}", 
        produces = { "application/json" },  
        method = RequestMethod.GET) 
    default ResponseEntity<Pet> showPetById(@ApiParam(value = "The id of the pet to retrieve",required=true) @PathVariable("petId") String petId) { 
        getRequest().ifPresent(request -> { 
            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { 
                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { 
                    ApiUtil.setExampleResponse(request, "application/json", "null"); 
                    break; 
                } 
            } 
        }); 
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); 
 
    } 
 
} 

所以我的问题是:我能找到的所有内容都表明 Spring Controller 是多线程的,可以同时处理多个请求。代码生成器坏了吗?我的解释完全错误吗?

PetsApiController 的构造函数让我停顿了一下。如果每个请求 Autowiring 一次,那么这意味着每个请求只有一个?

    @org.springframework.beans.factory.annotation.Autowired 
    public PetsApiController(NativeWebRequest request) { 
        this.request = request; 
    } 

请您参考如下方法:

swagger 代码生成器是出了名的不好,我的 friend 说生成器有广度但没有深度。您可以为各种语言和框架生成骨架,但它们有严重的局限性。例如,尝试使用 Page<Something> 从 SwaggerDoc 生成一个好的框架。或其他泛型。我会非常遗憾地说,它们几乎没有实用性,而且这些工具往往只能以相反的方式可靠地工作,即先编码,然后生成 SwaggerDoc。

我工作过的一个地方有一个很棒的概念,我真的很喜欢它,你可以在实现它之前先设计你的 API,这听起来像是你正在尝试做的。一些 IDE 甚至支持生成代码,并且有用于构建工具的插件,例如 maven gradle 等,可以从您的 yaml 生成代码。

但在实践中,我花了几天时间试图从这些工具中获得理想的结果并放弃了。我认为真正的问题是 Swagger/OpenAPI 仍然被广泛视为文档工具,而不是设计工具。我还认为,尝试创建一个包罗万象的项目生成器从一开始就注定要失败。

我自己尝试自定义生成器使用的 mustache 模板,但 Java 中的泛型是一场噩梦,你无法获得正确的工作流程,因此我会更改 SwaggerDoc 然后更新我的代码,因为我的方法是生成一个接口(interface),然后实现该接口(interface),但注释没有被继承,所以我不得不复制所有代码,这意味着没有任何好处。


标签:Spring Boot
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号