5

2つのサーバー(ApacheとJBoss AS7)があり、すべてのhttpメソッドへのアクセスをクライアントに提供する必要があります。これらのリクエストはすべてajax経由で送信する必要があります。クライアントコードの例:

$.ajax({
      type: "get",
      url: "http://localhost:9080/myproject/services/mobile/list",
      crossDomain: true,
      cache: false,
      dataType: "json",
      success: function(response) {
        console.log(response);
      },
      error: function (jqXHR, textStatus, errorThrown) {
        console.log(textStatus);
        console.log(jqXHR.responseText);
        console.log(errorThrown);
        }
    });

JBoss AS7では、RESTEasyを使用して、次のようにCORSを実装しています。

@Path("/mobile")
@Provider
@ServerInterceptor
public class GroupMobile implements MessageBodyWriterInterceptor {

@Inject
private GroupDAO groupDAO;

@GET
@Path("/list")
@Produces(MediaType.APPLICATION_JSON)
public List<Group> getGroups() {
    return groupDAO.listAll();
}

@Override
public void write(MessageBodyWriterContext context) throws IOException,
        WebApplicationException {
    context.getHeaders().add("Access-Control-Allow-Origin", "*");
    context.proceed();
}

@OPTIONS
@Path("/{path:.*}")
public Response handleCORSRequest(
        @HeaderParam("Access-Control-Request-Method") final String requestMethod,
        @HeaderParam("Access-Control-Request-Headers") final String requestHeaders) {
    final ResponseBuilder retValue = Response.ok();

    if (requestHeaders != null)
        retValue.header("Access-Control-Allow-Headers", requestHeaders);

    if (requestMethod != null)
        retValue.header("Access-Control-Allow-Methods", requestMethod);

    retValue.header("Access-Control-Allow-Origin", "*");

    return retValue.build();
}
}

web.xmlとbeans.xmlは空のファイルです。MyIP:8080(Apache)にアクセスすると、次のエラーメッセージが表示されます。

XMLHttpRequest cannot load http://localhost:9080/myproject/services/mobile/list?_=1359480354190. Origin http://MyIP:8080 is not allowed by Access-Control-Allow-Origin.

誰かが何が悪いのか知っていますか?

4

5 に答える 5

11

最新のresteasy(3.0.9-Final)には、ユーティリティクラスが含まれていますorg.jboss.resteasy.plugins.interceptors.CorsFilter

CorsFilterオブジェクトをアプリケーションのシングルトンオブジェクトセットに追加することも、ResteasyDeploymentのProviderFactoryに直接追加することもできます。

以下は、サンプルアプリケーションクラスです。

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;

import org.jboss.resteasy.plugins.interceptors.CorsFilter;


@ApplicationPath("/api")
public class RestApplication extends javax.ws.rs.core.Application {
    Set<Object> singletons;

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> clazzes = new HashSet<>();
        clazzes.add(VersionService.class);
        return clazzes;
    }

    @Override
    public Set<Object> getSingletons() {
        if (singletons == null) {
            CorsFilter corsFilter = new CorsFilter();
            corsFilter.getAllowedOrigins().add("*");

            singletons = new LinkedHashSet<Object>();
            singletons.add(corsFilter);
        }
        return singletons;
    }
}
于 2015-03-21T15:24:17.723 に答える
1

あなたが抱えている問題は、クロスサイトスクリプティングを行おうとしていることです。でページにアクセスしたhttp://MyIP:8080ため、ブラウザがそのドメイン外のリソースにアクセスできません。これは非常にブラウザ固有であり、ブラウザベースの回避策はすべて異なります(Chromeではグローバルに、IEではサイトごとにセキュリティを無効にすることができます)。

ページをとしてロードするとhttp://localhost:8080、クエリにアクセスできるようになります。または、リクエストを転送するプロキシを実装することもできます。

于 2013-01-29T18:09:38.250 に答える
1

この問題はhttps://issues.jboss.org/browse/RESTEASY-878に関連しているようです。でCORSプリフライトリクエストをキャッチできない場合がありますMessageBodyWriterInterceptor@WebFilter代わりにサーブレットフィルタ()を使用してみてください。

于 2013-12-26T13:20:16.303 に答える
1

さて、私は小さなソリューションを実装しました。最初にプロジェクトWebでインターセプターを実行し、「CORSInterceptor」というクラスを作成しました。

import org.jboss.resteasy.annotations.interception.ServerInterceptor;
import org.jboss.resteasy.core.ResourceMethod;
import org.jboss.resteasy.core.ServerResponse;
import org.jboss.resteasy.spi.Failure;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.interception.MessageBodyWriterContext;
import org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor;
import org.jboss.resteasy.spi.interception.PreProcessInterceptor;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Provider
@ServerInterceptor
public class CorsInterceptor implements PreProcessInterceptor, MessageBodyWriterInterceptor {

/**
     * The Origin header set by the browser at each request.
     */
    private static final String ORIGIN = "Origin";


 /**
     * The Access-Control-Allow-Origin header indicates which origin a resource it is specified for can be
     * shared with. ABNF: Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" source origin string | "*"
     */
    private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";


   //
    private static final ThreadLocal<String> REQUEST_ORIGIN = new ThreadLocal<String>();
    //
    private final Set<String> allowedOrigins;


 public CorsInterceptor(){
   this.allowedOrigins = new HashSet<String>();
   this.allowedOrigins.add("*");
 }

   @Override
    public ServerResponse preProcess(HttpRequest request, ResourceMethod method) throws Failure, WebApplicationException {
        if (!allowedOrigins.isEmpty()) {
            REQUEST_ORIGIN.set(request.getHttpHeaders().getRequestHeaders().getFirst(ORIGIN));
        }
        return null;
    }


@Override
public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException {
    if (!allowedOrigins.isEmpty() && (allowedOrigins.contains(REQUEST_ORIGIN.get()) || allowedOrigins.contains("*"))) {
        context.getHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, REQUEST_ORIGIN.get());
      }
    context.proceed();
    }
}

ファイルWeb.xmlに追加します

<context-param>
    <param-name>resteasy.providers</param-name>
    <param-value><package>.CorsInterceptor</param-value>
</context-param>

パッケージ:クラスのUbication。

使用したJQueryをリクエストします。

$.ajax({
    type: 'GET',
    dataType: "json", 

    crossDomain : true,

    cache:false, 
    url: "http://localhost:12005/ProyectoWebServices/ws/servicioTest",
    success: function (responseData, textStatus, jqXHR) {
       alert("Successfull: "+responseData);
    },
    error: function (responseData, textStatus, errorThrown) {
        alert("Failed: "+responseData);
    }
});

それは私にとってはうまくいきました。お役に立てば幸いです。

于 2014-07-24T05:06:30.197 に答える
0

私は最近同じ問題に直面し、私のために働いた私の解決策を追加しました:

以下は私がしたことです:

  • javax.ws.rs.core.Applicationを拡張するクラスを作成し、それにCorsFilterを追加しました。

CORSフィルターに、を追加しましcorsFilter.getAllowedOrigins().add("http://localhost:4200");た。

基本的に、クロスオリジンリソースシェアリングを許可するURLを追加する必要があります。特定のURLの代わりに使用"*"して任意のURLを許可することもできます。

public class RestApplication
    extends Application
{
    private Set<Object> singletons = new HashSet<Object>();

    public MessageApplication()
    {
        singletons.add(new CalculatorService()); //CalculatorService is your specific service you want to add/use.
        CorsFilter corsFilter = new CorsFilter();
        // To allow all origins for CORS add following, otherwise add only specific urls.
        // corsFilter.getAllowedOrigins().add("*");
        System.out.println("To only allow restrcited urls ");
        corsFilter.getAllowedOrigins().add("http://localhost:4200");
        singletons = new LinkedHashSet<Object>();
        singletons.add(corsFilter);
    }

    @Override
    public Set<Object> getSingletons()
    {
        return singletons;
    }
}
  • そして、これが私のweb.xmlです。
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Restful Web Application</display-name>

    <!-- Auto scan rest service -->
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.app.RestApplication</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

</web-app>

あなたが必要としないかもしれないか、次のように変更するかもしれないいくつかのカスタム変更があります:

    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

また

    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>

また

    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </context-param>

この問題が発生したときに欠落していた 最も重要なコードは、javax.ws.rs.Application、つまりRestApplicationを拡張するクラスをのinit-paramに追加していなかったことです。<servlet-name>resteasy-servlet</servlet-name>

   <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.app.RestApplication</param-value>
    </init-param>

そのため、フィルターを実行できなかったため、アプリケーションは指定されたURLからのCORSを許可していませんでした。

PS:私はRestEasyバージョンを使用しています:3.12.1.Final

于 2020-07-18T12:06:10.027 に答える