Включить CORS в Java Play Framework 2.2.x
У меня возникает проблема включения кросс-домена в 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 не является абстрактным и не отменяет вызов абстрактного метода (Контекст) в действии...
Есть ли эквивалентный код для java play 2.2.x?
Спасибо.
Ответы
Ответ 1
Он выглядит следующим образом:
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));
}
}
Ответ 2
Для тех, кто использует 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));
}
}
Ответ 3
Решения, предлагаемые @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()));
}
}
Ответ 4
Другим вариантом может быть использование Filters. В настоящее время доступны только Scala фильтры. Однако, как указано в этом сообщении, для простое изменение заголовков ответов вы можете скопировать и вставить следующее, чтобы включить 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};
}