Весна JSON-P с Джексоном

Пружина JSON-P с Джексоном

1. обзор

Если вы что-то разрабатываете в Интернете, вы знаете, что браузерыthe same-origin policy constraint работают с запросами AJAX. Простой обзор ограничения заключается в том, что любой запрос, исходящий из другого домена, схемы или порта, не будет разрешен.

Один из способов использоватьrelax this browser restriction при работе с данными JSON - использовать JSON с заполнением (JSON-P).

В этой статье обсуждается поддержка Spring для работы с данными JSON-P с помощьюAbstractJsonpResponseBodyAdvice.

2. JSON-P в действии

Политика одного и того же происхождения не применяется к тегу<script>, что позволяет загружать сценарии в разных доменах. Техника JSON-P использует это преимущество, передавая ответ JSON в качестве аргумента функции javascript.

2.1. подготовка

В наших примерах мы будем использовать этот простой классCompany:

public class Company {

    private long id;
    private String name;

    // standard setters and getters
}

Этот класс будет связывать параметры запроса и должен быть возвращен с сервера в виде JSON-представления.

Метод контроллера также является простой реализацией - возвращает экземплярCompany:

@RestController
public class CompanyController {

    @RequestMapping(value = "/companyRest",
      produces = MediaType.APPLICATION_JSON_VALUE)
    public Company getCompanyRest() {
        Company company = new Company(1, "Xpto");
        return company;
    }
}

На стороне клиента мы можем использовать библиотекуjQuery для создания и отправки запроса AJAX:

$.ajax({
    url: 'http://localhost:8080/spring-mvc-java/companyRest',
    data: {
        format: 'json'
    },
    type: 'GET',
    ...
});

Рассмотрим запрос AJAX для следующего URL:

http://localhost:8080/spring-mvc-java/companyRest

Ответ от сервера будет следующим:

{"id":1,"name":"Xpto"}

Поскольку запрос был отправлен по той же схеме, домену и порту, ответ не будет заблокирован, и данные JSON будут разрешены браузером.

2.2. Запрос на другой источник

Изменив URL запроса на:

http://127.0.0.1:8080/spring-mvc-java/companyRest

ответ будет заблокирован браузером из-за того, что запрос отправлен отlocalhost к127.0.0.1, который считается другим доменом и представляет собой нарушение политики того же происхождения.

С помощью JSON-P мы можем добавить параметр обратного вызова в запрос:

http://127.1.1.1:8080/spring-mvc-java/companyRest?callback=getCompanyData

На стороне клиента это так же просто, как добавить следующие параметры в запрос AJAX:

$.ajax({
    ...
    jsonpCallback:'getCompanyData',
    dataType: 'jsonp',
    ...
});

getCompanyData будет функцией, вызываемой при получении ответа.

Если сервер форматирует ответ следующим образом:

getCompanyData({"id":1,"name":"Xpto"});

браузеры не будут блокировать его, так как он будет рассматривать ответ как сценарий, согласованный и согласованный между клиентом и сервером из-за совпаденияgetCompanyData как в запросе, так и в ответе.

3. @ControllerAdvice Аннотация

Компоненты, помеченные@ControllerAdvice, могут помочь всем или определенному подмножеству контроллеров и используются для инкапсуляции сквозного поведения, совместно используемого различными контроллерами. Типичные шаблоны использования связаны сexception handling,adding attributes to models или регистрирующими связующими.

Starting with Spring 4.1,@ControllerAdvice может регистрировать реализации интерфейсаResponseBodyAdvice, который позволяет изменять ответ после того, как он был возвращен методом контроллера, но перед записью подходящим конвертером.

4. Изменение ответа с помощьюAbstractJsonpResponseBodyAdvice

Also starting with Spring 4.1, теперь у нас есть доступ к классуAbstractJsonpResponseBodyAdvice, который форматирует ответ в соответствии со стандартами JSON-P.

В этом разделе объясняется, как задействовать базовый класс и изменить ответ, не внося никаких изменений в существующие контроллеры.

Чтобы включить поддержку Spring для JSON-P, давайте начнем с настройки:

@ControllerAdvice
public class JsonpControllerAdvice
  extends AbstractJsonpResponseBodyAdvice {

    public JsonpControllerAdvice() {
        super("callback");
    }
}

Подставка выполняется с использованием классаAbstractJsonpResponseBodyAdvice. Ключ, передаваемый в методе super, будет использоваться в URL, запрашивающем данные JSON-P.

С этим советом контроллера мы автоматически конвертируем ответ в JSON-P.

5. JSON-P с Spring на практике

С помощью ранее обсужденной конфигурации мы можем заставить наши REST-приложения реагировать с помощью JSON-P. В следующем примере мы вернем данные компании, поэтому URL-адрес нашего запроса AJAX должен быть примерно таким:

http://127.0.0.1:8080/spring-mvc-java/companyRest?callback=getCompanyData

В результате предыдущей конфигурации ответ будет выглядеть следующим образом:

getCompanyData({"id":1,"name":"Xpto"});

Как уже говорилось, ответ в этом формате не будет заблокирован, несмотря на то, что он исходит из другого домена.

JsonpControllerAdvice можно легко применить к любому методу, который возвращает ответ, помеченный@ResponseBody иResponseEntity.

Должна быть функция с тем же именем, переданная в обратном вызове,getCompanyData, для обработки всех ответов.

6. Заключение

В этой быстрой статье показано, как упростить в других случаях утомительную работу по форматированию ответа с использованием JSON-P с помощью новой функциональности в Spring 4.1.

Реализацию примеров и фрагментов кода можно найти в этомGitHub project.