Play Framework 2.6重写call方法抛出Throwable编译报错求助
解决Play Framework 2.6中Action重写call方法的编译错误
这个问题我之前做Play项目时也踩过坑,其实根源就是方法重写的异常抛出规则:你子类里的call方法声明了throws Throwable,但父类play.mvc.Action的call方法并没有声明抛出任何checked异常,这直接违反了Java的重写规则——子类重写的方法不能抛出比父类更多或更宽泛的checked异常。
具体原因分析
Play 2.6的play.mvc.Action接口中,call方法的签名是这样的:
CompletionStage<Result> call(Http.Context ctx);
它没有任何throws声明,意味着这个方法不会抛出checked异常,所有异常都应该通过CompletionStage来异步处理。而你的代码给子类方法加了throws Throwable,编译器自然会报错。
解决方案
只需要两步就能搞定:
- 去掉
call方法的throws Throwable声明 - 如果
delegate.call(ctx)可能产生异常,用CompletionStage的异步API来处理(比如exceptionally)
修改后的代码如下:
public CompletionStage<Result> call(final Http.Context ctx) { ctx.response().setHeader("Access-Control-Allow-Origin", "*"); ctx.response().setHeader("Allow", "*"); ctx.response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS"); ctx.response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent, token"); ctx.response().setHeader("Access-Control-Expose-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent, token"); return delegate.call(ctx) .exceptionally(ex -> { // 这里可以根据业务需求处理异步异常,比如返回自定义错误Result return Results.internalServerError("请求处理失败"); }); }
额外说明
Play 2.x版本开始全面推崇异步编程,所有异步操作的异常都应该通过CompletionStage的回调来处理,而不是用传统的throws方式抛出,这样既契合异步模型的设计理念,也能避免编译层面的异常检查问题。
内容的提问来源于stack exchange,提问作者sarah w
相关产品推荐
相关产品推荐

