Spring Boot 2中OpenApi生成@RequestMapping接口实现请求不触发问题
解决Spring Boot实现OpenApi接口时自定义方法不被调用的问题
这个问题的核心原因是OpenApi Generator默认生成的接口方法带有default实现,而Spring MVC在处理请求时,会优先选择接口中带有@RequestMapping注解的default方法,而非你编写的实现类中的重写方法。
为什么会出现这个问题?
你生成的PassbookApi接口里的fetchPassbook是一个default方法,它自带@RequestMapping注解且默认返回NOT_IMPLEMENTED。Spring会把这个default方法注册为请求处理的HandlerMethod,所以请求进来时直接调用了接口的默认实现,根本不会走到你的PassbookController里的自定义方法。
解决方案:修改OpenApi Generator配置,移除接口方法的Default实现
只需要在你的openapi-generator-maven-plugin的configOptions里添加一个参数,让生成的接口方法变成抽象方法,不带默认实现:
<configOptions> <!-- 保留你现有的其他配置 --> <dateLibrary>java8-localdatetime</dateLibrary> <java8>true</java8> <interfaceOnly>true</interfaceOnly> <reactive>false</reactive> <useBeanValidation>true</useBeanValidation> <performBeanValidation>true</performBeanValidation> <useOptional>false</useOptional> <serviceInterface>true</serviceInterface> <serviceImplementation>false</serviceImplementation> <!-- 添加这一行 --> <skipDefaultInterface>true</skipDefaultInterface> </configOptions>
生成后的接口变化
添加这个配置后,重新生成的PassbookApi接口里的fetchPassbook会变成抽象方法,不再有默认实现:
@Validated @Api(value = "passbook", description = "the passbook API") public interface PassbookApi { default Optional<NativeWebRequest> getRequest() { return Optional.empty(); } @ApiOperation(value = "Get passbook information for a given account number", nickname = "fetchPassbook", notes = "", response = PagedTransactionDetails.class, tags={ "passbook", }) @ApiResponses(value = { @ApiResponse(code = 200, message = "Passbook information", response = PagedTransactionDetails.class), @ApiResponse(code = 400, message = "Bad Request"), @ApiResponse(code = 500, message = "Internal Server Error"), @ApiResponse(code = 401, message = "Unauthorized") }) @RequestMapping(value = "/passbook", produces = { "application/json" }, method = RequestMethod.GET) ResponseEntity<PagedTransactionDetails> fetchPassbook(@NotNull @ApiParam(value = "Account Number", required = true) @Valid @RequestParam(value = "accountNumber", required = true) String accountNumber,@ApiParam(value = "Offset for transactions to be displayed") @Valid @RequestParam(value = "offset", required = false) Integer offset,@ApiParam(value = "Last transaction serial number") @Valid @RequestParam(value = "transactionSerialNumber", required = false) String transactionSerialNumber,@ApiParam(value = "Last transactionId") @Valid @RequestParam(value = "transactionId", required = false) String transactionId,@ApiParam(value = "Last amount value") @Valid @RequestParam(value = "amountValue", required = false) Integer amountValue); }
验证效果
现在你的PassbookController不需要做任何修改,只要保持实现PassbookApi接口并重写fetchPassbook方法即可。Spring MVC会识别到实现类的方法继承了接口上的@RequestMapping注解,将其注册为请求处理方法,请求进来时就会正确调用你自定义的实现了。
额外说明
- 确保你的
PassbookController被Spring扫描到(已经加了@RestController,只要在@SpringBootApplication的扫描范围内就没问题)。 - 这个方案适用于Spring Boot 2.1.x版本,和你当前使用的
spring-boot-starter-web(v2.1.5)完全兼容。
内容的提问来源于stack exchange,提问作者Kumar Sambhav
相关产品推荐
相关产品推荐

