Перейти к основному содержимому

CORS в JAX-RS

· 3 мин. чтения

1. Обзор

В этой быстрой статье мы узнаем, как включить CORS ( совместное использование ресурсов между источниками) в системе на основе JAX-RS . Мы настроим приложение поверх JAX-RS , чтобы включить механизм CORS .

2. Как включить механизм CORS

Есть два способа включить CORS в JAX-RS. Первый и самый простой способ — создать фильтр для ввода необходимого заголовка ответа во время выполнения каждого запроса. Другой — вручную добавить соответствующий заголовок в каждую конечную точку URL.

В идеале следует использовать первое решение; однако, когда это невозможно, более ручной вариант также технически приемлем.

2.1. Использование фильтра

JAX-RS имеет интерфейс ContainerResponseFilter , реализованный фильтрами ответа контейнера. Как правило, этот экземпляр фильтра применяется глобально к любому ответу HTTP.

Мы реализуем этот интерфейс для создания пользовательского фильтра, который будет вставлять заголовок Access-Control-Allow-* в каждый исходящий запрос и включать механизм CORS :

@Provider
public class CorsFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
responseContext.getHeaders().add(
"Access-Control-Allow-Origin", "*");
responseContext.getHeaders().add(
"Access-Control-Allow-Credentials", "true");
responseContext.getHeaders().add(
"Access-Control-Allow-Headers",
"origin, content-type, accept, authorization");
responseContext.getHeaders().add(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}

Пара моментов здесь:

  • Фильтры, реализующие ContainerResponseFilter , должны быть явно аннотированы с помощью @Provider , чтобы их могла обнаружить среда выполнения JAX-RS.
  • Мы добавляем в заголовок ' Access-Control-Allow-* ' '*', что означает, что к любым конечным точкам URL этого экземпляра сервера можно получить доступ через любой домен; если мы хотим явно ограничить междоменный доступ, мы должны упомянуть этот домен в этом заголовке

2.2. Использование модификации заголовка в каждой конечной точке

Как указывалось ранее, мы также можем явно внедрить заголовок Access-Control-Allow-* на уровне конечной точки:

@GET
@Path("/")
@Produces({MediaType.TEXT_PLAIN})
public Response index() {
return Response
.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization")
.header("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD")
.entity("")
.build();
}

Здесь следует отметить, что если мы пытаемся включить CORS в большом приложении, нам не следует пробовать этот метод, потому что в этом случае нам придется вручную вставлять заголовок в каждую конечную точку URL-адреса, что приведет к дополнительным накладным расходам.

Однако этот метод можно использовать в приложениях, где нам нужно включить CORS только для некоторых конечных точек URL.

3. Тестирование

Как только приложение запущено, мы можем протестировать заголовки с помощью команд curl. Пример вывода заголовков должен выглядеть примерно так:

HTTP/1.1 200 OK
Date : Tue, 13 May 2014 12:30:00 GMT
Connection : keep-alive
Access-Control-Allow-Origin : *
Access-Control-Allow-Credentials : true
Access-Control-Allow-Headers : origin, content-type, accept, authorization
Access-Control-Allow-Methods : GET, POST, PUT, DELETE, OPTIONS, HEAD
Transfer-Encoding : chunked

Более того, мы можем создать простую функцию AJAX и проверить междоменную функциональность:

function call(url, type, data) {
var request = $.ajax({
url: url,
method: "GET",
data: (data) ? JSON.stringify(data) : "",
dataType: type
});

request.done(function(resp) {
console.log(resp);
});

request.fail(function(jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
};

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

Вы можете легко сделать это локально, запустив клиентское приложение на отдельном порту , поскольку порт определяет источник.

4. Вывод

В этой статье мы показали реализацию механизма CORS в приложениях на основе JAX-RS.

Как всегда, полный исходный код доступен на GitHub .