【问题标题】:Enable CORS in Java Play Framework 2.2.x在 Java Play Framework 2.2.x 中启用 CORS
【发布时间】: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 有没有等价的代码?

谢谢。

【问题讨论】:

    标签: java playframework cors playframework-2.2


    【解决方案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&lt;Result&gt; 而不是 Promise&lt;SimpleResult&gt;

        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));
              }
          }
          

          【讨论】:

          • 我们使用了这种方法,但遇到了导致错误的请求问题。我们稍微更改了代码,以便在调用委托之前设置响应标头。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-15
          相关资源
          最近更新 更多