Scala重写Swagger生成的Java接口时出现冲突错误求助
解决Scala重写Swagger生成接口时的override矛盾问题
先还原下你的场景:Swagger Codegen生成了带默认实现的Java接口方法,你用Scala重写时遇到了两难——不加override提示方法已定义,加了又提示没东西可重写。我来帮你拆解原因和解决办法:
先看你的代码场景
Swagger生成的Java接口方法
@ApiOperation(value = "", nickname = "submitJob", notes = "Execute a job", response = GetJob.class, tags={ "jobs", }) @ApiResponses(value = { @ApiResponse(code = 200, message = "Get job info", response = GetJob.class) }) @RequestMapping(value = "/api/v1/jobs/{requestId}", produces = { "application/json" }, method = RequestMethod.PUT) default ResponseEntity<GetJob> submitJob( @ApiParam(value = "",required=true) @PathVariable("requestId") UUID requestId, @ApiParam(value = "Job to be submitted" ,required=true ) @Valid @RequestBody JobRequest body ) { // 默认实现逻辑... }
你的Scala重写代码
@ApiOperation(value = "", nickname = "submitJob", notes = "Execute a job", response = classOf[GetJob], tags = Array("jobs")) @ApiResponses(value = Array(new ApiResponse(code = 200, message = "Get job info", response = classOf[GetJob]))) @RequestMapping(value = Array("/api/v1/jobs/{requestId}"), produces = Array("application/json"), method = Array(RequestMethod.PUT)) override def submitJob( @ApiParam(value = "", required = true) @PathVariable("requestId") requestId: UUID, @ApiParam(value = "Job to be submitted", required = true) @Valid @RequestBody body: JobRequest ): ResponseEntity[GetJob] = { // 自定义逻辑... }
问题根源
这个矛盾完全是Java默认方法和Scala语法规则的兼容性问题:
- Java默认方法的特殊性:生成的
submitJob是Java 8引入的default方法——它属于接口方法,但自带默认实现,不是抽象方法。 - Scala的处理逻辑:
- 不加
override时,Scala会把你的方法当成类中新定义的方法,但接口里已经存在同名同签名的default方法,所以编译器认为“方法已在作用域中定义”。 - 加
override时,Scala会检查是否有抽象方法需要重写,但Java的default方法不是抽象方法,所以编译器提示“没有可重写的方法”。
- 不加
另外还有一种可能:你的Scala类没有正确继承Swagger生成的Java接口,或者方法签名(比如UUID的类型、实体类的包名)和接口不完全匹配,也会触发这个错误。
解决方案
1. 先确保正确继承接口
首先检查你的Scala类是否明确extends了Swagger生成的Java接口(比如接口名为JobsApi):
// 替换成你实际生成的接口类名 class JobController extends JobsApi { // 在这里实现submitJob方法 }
2. 严格匹配方法签名
确认参数和返回类型和Java接口完全一致:
- 比如
UUID要使用java.util.UUID(和Java接口中的类型一致,不要用Scala自带的scala.util.UUID) - 确认
GetJob、JobRequest都是Swagger生成的类,包名完全匹配
3. 用Scala 2.12+的正确语法覆盖默认方法
Scala 2.12及以后版本完美支持Java默认方法,覆盖时必须加override,同时对齐注解配置:
class JobController extends JobsApi { @ApiOperation(value = "", nickname = "submitJob", notes = "Execute a job", response = classOf[GetJob], tags = Array("jobs")) @ApiResponses(value = Array(new ApiResponse(code = 200, message = "Get job info", response = classOf[GetJob]))) @RequestMapping(value = Array("/api/v1/jobs/{requestId}"), produces = Array("application/json"), method = Array(RequestMethod.PUT)) override def submitJob( @ApiParam(value = "", required = true) @PathVariable("requestId") requestId: java.util.UUID, @ApiParam(value = "Job to be submitted", required = true) @Valid @RequestBody body: JobRequest ): ResponseEntity[GetJob] = { // 这里写你的业务逻辑 val jobResult = GetJob(/* 构造返回对象 */) ResponseEntity.ok(jobResult) } }
4. 备选方案:让Swagger生成抽象方法
如果上述方法仍有问题,可以修改Swagger Codegen的配置,让它生成抽象方法而非default方法。比如在Maven插件中添加配置:
<plugin> <groupId>io.swagger</groupId> <artifactId>swagger-codegen-maven-plugin</artifactId> <version>2.4.27</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>src/main/resources/swagger.yaml</inputSpec> <language>java</language> <apiPackage>com.your.package.api</apiPackage> <!-- 开启这个配置,生成抽象接口方法 --> <interfaceOnly>true</interfaceOnly> <skipDefaultInterface>true</skipDefaultInterface> </configuration> </execution> </executions> </plugin>
这样生成的Java接口中submitJob会是抽象方法,此时Scala类实现时加override就不会有任何矛盾了。
内容的提问来源于stack exchange,提问作者Gritty Kitty
相关产品推荐
相关产品推荐

