REST Jersey 2.x: JSONP (part 3)
Один из способов кроссдоменной коммуникации это jsonp. Json with Padding. Это не формат данных, а принцип взаимодействия с внешним доменом. Даже если обращаемся в этому же домену, но к другому порту, браузер считает такой урл внешним и обычные способы взаимодействия уже не сработают.
Принцип прост - сервер возвращает данные формата json обернутые в функцию яваскрипт. callback({"data":123});
клиент добавляет на страницу тег <script>, src которого урл веб сервиса, т.о. скрипт получает яваскрипт код (callback(....)), . Затем вызывается существуюая функция callback, в которой обрабатываются принятые json данные.
Запущу мини пример с Jersey реализацией.
Tomcat 7
Netbeans 7.4
Jersey 2.4.1
Есть такой обычный сервис:
@Path(value = "/") public class JerseyService { @GET @Path("/catp") @Produces(MediaType.APPLICATION_JSON) public CrazyCat getMyCat(){ CrazyCat cat = new CrazyCat(); cat.setEyes("blue"); return cat; } }
Сделать из него Jsonp очень просто. В Jersey 2.x появилась для этого аннотация @JSONP. В ней и задается назавание обрабатывающей функции, по умолчанию callback.
Согласно документации изменю возвращаемый тип на "application/x-javascript".
Итого:
@Path(value = "/") public class JerseyService { @GET @Path("/catp") @JSONP @Produces({"application/x-javascript"}) public CrazyCat getMyCat(){ CrazyCat cat = new CrazyCat(); cat.setEyes("blue"); return cat; } }
Теперь метод возващает jsonp:
callback({"eyes":"blue"})
Дело за малым, обработка на клиенте :
function callback(data) { var color = data["eyes"]; var el = document.getElementById("answer"); el.innerHTML = color; el.style.color = color; }
А так же создание скрипта:
function createScript() { var urlJsonp = "http://localhost:8080/JerseyJSONP/rest/catp"; var scriptElem = document.createElement("script"); scriptElem.type = "text/javascript"; scriptElem.src = urlJsonp; document.getElementsByTagName("head")[0].appendChild(scriptElem); }Теперь все готово. По нажатию на кнопку вызывается создание скрипта, получаем данные jsonp, инъектим на страницу, вызывается обработчик callback.
Вот что получилось.
Пример |
Инъекция скрипта |
Функция не обязательно должна называться callback. Укажу в сервисе:
@JSONP(callback = "takeCat")
Теперь на странице другой обработчик:
Название функции обработчика задается в веб сервисе. |
Еще способ - передать имя через параметр:
На клиенте добавляю к урл параметр с названием функции обработчика. И саму функцию:
var urlJsonp = "http://localhost:8080/JerseyJSONP/rest/catp?call=receiveCat"; ... function receiveCat(data){ ... }На сервере указывается какой параметр содержит название оборачивающей функции:
@JSONP(queryParam = "call")Получаем другого обработчика:
Название функции обработчика задается на клиенте. |
По теме:
Svn сего действа.
Про jsonp, а так же пример с jQ.