Пружина 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.