Я работаю над веб-приложением, состоящим из UI-Angular, Server-Java, RestEasy 3.0.9.Final для остальных вызовов api

Когда я пытался получить доступ к остальной службе из другого домена, я получаю ошибку ниже

НЕВОЗМОЖНО ЗАГРУЗИТЬ Ответ на предварительный запрос не проходит проверку контроля доступа: для запрошенного ресурса нет заголовка «Access-Control-Allow-Origin». Следовательно, к источнику 'http: // localhost: 8080' не разрешен доступ.

Я настроил свою серверную часть для ответа на междоменные вызовы, и это работает с вызовом GET, но вызов POST создает ОШИБКУ

web.xml

<context-param>
    <param-name>resteasy.providers</param-name>
    <param-value>com.test.sample.app.CorsFeature</param-value>
</context-param>

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


<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</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.test.sample.app.Application</param-value>
    </init-param>
</servlet>

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

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

Класс обслуживания

@GET
@Path("/getnameAtt")
@Produces(MediaType.APPLICATION_JSON)
public Response getHostnameAttributes() {
return Response
.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers",
        "origin, content-type, accept, authorization")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Allow-Methods",
        "GET, POST, PUT, DELETE, OPTIONS, HEAD")
.header("Access-Control-Max-Age", "1209600")
.entity(new TestImpl().getHostNameAttributes())
.build();
}

@POST
@Path("/getSeq")
@Produces(MediaType.APPLICATION_JSON)
public Response getCurrentSequence(String request) {
return Response
.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers",
        "origin, content-type, accept, authorization")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Allow-Methods",
        "GET, POST, PUT, DELETE, OPTIONS, HEAD")
.header("Access-Control-Max-Age", "1209600")
.entity(new TestImpl().getCurrentSeq(request))
.build();
}

Поскольку я новичок в рестилинге, не могу понять, почему это не работает. Любая помощь будет принята с благодарностью. Ждем вашего ответа.

Благодарность

22
PremKumarR 16 Окт 2015 в 10:16

3 ответа

Лучший ответ

Ваши методы ресурсов не будут затронуты, поэтому их заголовки никогда не будут установлены. Причина в том, что существует так называемый предварительный запрос перед фактическим запросом, который является запросом OPTIONS. Таким образом, ошибка возникает из-за того, что предварительный запрос не создает необходимых заголовков.

Для RESTeasy следует использовать CorsFilter. Вы можете увидеть здесь пример того, как его настроить. Этот фильтр будет обрабатывать предполетный запрос. Таким образом, вы можете удалить все те заголовки, которые есть в ваших ресурсных методах.

См. также .

11
Community 23 Май 2017 в 12:25

Столкнувшись с подобной проблемой, я сделал следующее:

  • Создал класс, расширяющий javax.ws.rs.core.Application, и добавил к нему Cors Filter.

В фильтр CORS я добавил corsFilter.getAllowedOrigins().add("http://localhost:4200");.

По сути, вы должны добавить URL-адрес, по которому вы хотите разрешить совместное использование ресурсов из разных источников. Ans, вы также можете использовать "*" вместо любого конкретного 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>

Самый важный код , которого мне не хватало, когда я столкнулся с этой проблемой, заключался в том, что я не добавлял свой класс, расширяющий javax.ws.rs.Application, т.е. RestApplication, в параметр инициализации <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>

И поэтому мой фильтр не смог выполнить, и, следовательно, приложение не разрешало CORS с указанного URL-адреса.

0
Golu 18 Июл 2020 в 12:13

Похоже, ваш метод ресурса POST не получит упоминания @peeskillet. Скорее всего, ваш запрос ~ POST ~ не будет работать, потому что это может быть непростой запрос. Единственными простыми запросами являются GET, HEAD или POST, а заголовки запросов просты (единственными простыми заголовками являются Accept, Accept-Language, Content-Language, Content-Type = application / x-www-form-urlencoded, multipart / form-data , текст / обычный).

Поскольку вы уже добавили заголовки Access-Control-Allow-Origin в свой ответ, вы можете добавить новый метод OPTIONS в свой класс ресурсов.

    @OPTIONS
@Path("{path : .*}")
public Response options() {
    return Response.ok("")
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "2000")
            .build();
}
0
Ranuka 6 Дек 2016 в 11:18