在 Java Play Framework 2.2.x 中启用 CORS
Posted
技术标签:
【中文标题】在 Java Play Framework 2.2.x 中启用 CORS【英文标题】:Enable CORS in Java Play Framework 2.2.x 【发布时间】:2014-04-04 09:13:47 【问题描述】:我无法在 Java Play 2.2.x 中启用跨域
在 Java Play 2.1.3 中,此代码通过将其放入 Global.java 中来工作
public class Global extends GlobalSettings
private class ActionWrapper extends Action.Simple
public ActionWrapper(Action action)
this.delegate = action;
@Override
public Result call(Http.Context ctx) throws java.lang.Throwable
Result result = this.delegate.call(ctx);
Http.Response response = ctx.response();
response.setHeader("Access-Control-Allow-Origin", "*");
return result;
@Override
public Action onRequest(Http.Request request, java.lang.reflect.Method actionMethod)
return new ActionWrapper(super.onRequest(request, actionMethod));
但是当我尝试在 java play 2.2.x 上编译时,它不再编译了。
编译错误信息:
Global.ActionWrapper 不是抽象的,不会覆盖 Action 中的抽象方法 call(Context) ...
java play 2.2.x 有没有等价的代码?
谢谢。
【问题讨论】:
【参考方案1】:@alexhanschke 提出的解决方案在请求引发异常(内部服务器错误)时不起作用,因为发生这种情况时不会应用过滤器(请参阅https://github.com/playframework/playframework/issues/2429)。为了解决这个问题,您必须包装一个 scala 类并将其作为结果返回,如下所示。请注意,这仍然需要指定的选项路由和一个控制器来处理选项请求。
在https://gist.github.com/tinusn/38c4c110f7cd1e1ec63f 处查看全部内容。
import static play.core.j.JavaResults.BadRequest;
import static play.core.j.JavaResults.InternalServerError;
import static play.core.j.JavaResults.NotFound;
import java.util.ArrayList;
import java.util.List;
import play.GlobalSettings;
import play.api.mvc.Results.Status;
import play.libs.F.Promise;
import play.libs.Scala;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;
import scala.Tuple2;
import scala.collection.Seq;
public class Global extends GlobalSettings
private class ActionWrapper extends Action.Simple
public ActionWrapper(Action<?> action)
this.delegate = action;
@Override
public Promise<Result> call(Http.Context ctx) throws java.lang.Throwable
Promise<Result> result = this.delegate.call(ctx);
Http.Response response = ctx.response();
response.setHeader("Access-Control-Allow-Origin", "*");
return result;
/*
* Adds the required CORS header "Access-Control-Allow-Origin" to successfull requests
*/
@Override
public Action<?> onRequest(Http.Request request, java.lang.reflect.Method actionMethod)
return new ActionWrapper(super.onRequest(request, actionMethod));
private static class CORSResult implements Result
final private play.api.mvc.Result wrappedResult;
public CORSResult(Status status)
List<Tuple2<String, String>> list = new ArrayList<Tuple2<String, String>>();
Tuple2<String, String> t = new Tuple2<String, String>("Access-Control-Allow-Origin","*");
list.add(t);
Seq<Tuple2<String, String>> seq = Scala.toSeq(list);
wrappedResult = status.withHeaders(seq);
public play.api.mvc.Result toScala()
return this.wrappedResult;
/*
* Adds the required CORS header "Access-Control-Allow-Origin" to bad requests
*/
@Override
public Promise<Result> onBadRequest(Http.RequestHeader request, String error)
return Promise.<Result>pure(new CORSResult(BadRequest()));
/*
* Adds the required CORS header "Access-Control-Allow-Origin" to requests that causes an exception
*/
@Override
public Promise<Result> onError(Http.RequestHeader request, Throwable t)
return Promise.<Result>pure(new CORSResult(InternalServerError()));
/*
* Adds the required CORS header "Access-Control-Allow-Origin" when a route was not found
*/
@Override
public Promise<Result> onHandlerNotFound(Http.RequestHeader request)
return Promise.<Result>pure(new CORSResult(NotFound()));
【讨论】:
【参考方案2】:另一个选项可能是使用Filters。目前只有 Scala 过滤器可用。但是,正如this post 中指出的那样,为了简单地修改响应标头,您可以复制并粘贴以下内容以启用 CORS。
package filters
import play.api.mvc._
import play.mvc.Http.HeaderNames
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
class EnableCORS extends Filter
def apply(f: (RequestHeader) => Future[Result])(rh: RequestHeader): Future[Result] =
val result = f(rh)
result.map(_.withHeaders(HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> "*"))
然后将过滤器添加到您的Global.java
中:
@Override
public <T extends EssentialFilter> Class<T>[] filters()
return new Class[] EnableCORS.class;
【讨论】:
【参考方案3】:对于使用 2.3.1+(截至撰写本文时)Play 的任何人,现在是 Promise<Result>
而不是 Promise<SimpleResult>
import play.GlobalSettings;
import play.libs.F.Promise;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;
public class Global extends GlobalSettings
private class ActionWrapper extends Action.Simple
public ActionWrapper(Action<?> action)
this.delegate = action;
@Override
public Promise<Result> call(Http.Context ctx) throws java.lang.Throwable
Promise<Result> result = this.delegate.call(ctx);
Http.Response response = ctx.response();
response.setHeader("Access-Control-Allow-Origin", "*");
return result;
@Override
public Action<?> onRequest(Http.Request request, java.lang.reflect.Method actionMethod)
return new ActionWrapper(super.onRequest(request, actionMethod));
【讨论】:
【参考方案4】:看起来像这样:
import play.GlobalSettings;
import play.libs.F.Promise;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.SimpleResult;
public class Global extends GlobalSettings
private class ActionWrapper extends Action.Simple
public ActionWrapper(Action<?> action)
this.delegate = action;
@Override
public Promise<SimpleResult> call(Http.Context ctx) throws java.lang.Throwable
Promise<SimpleResult> result = this.delegate.call(ctx);
Http.Response response = ctx.response();
response.setHeader("Access-Control-Allow-Origin", "*");
return result;
@Override
public Action<?> onRequest(Http.Request request, java.lang.reflect.Method actionMethod)
return new ActionWrapper(super.onRequest(request, actionMethod));
【讨论】:
我们使用了这种方法,但遇到了导致错误的请求问题。我们稍微更改了代码,以便在调用委托之前设置响应标头。以上是关于在 Java Play Framework 2.2.x 中启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Play Framework JSON Rest 上使用 java.time.LocalDate?
Play Framework Java - 包 play.db 不存在
缺少包'play.filters.cors.CORSFilter' - Play Framework 2.4.6 (Java)