Мне нужно обеспечить хранение и получение токена доступа в локальном хранилище. Сейчас я смог сделать отправку данных в хранилище, но не могу получить эти данные от туда.
Пример кода для отправки данных в local storage:
Page page = UI.getCurrent().getPage();
page.getJavaScript().execute(“localStorage.setItem(’” + name + “’, '” + token + “’)”);
Проблема в том, что метод execute() является void методом, а я бы хотел получить эти данные в java коде. Методы Vaadin, например, executeJs() - недоступны в jmix.
Можно попробовать создать функцию js которая вернет значение через JavaScript.getCurrent().addFunction
и вызывать ее в нужный момент через page.getJavaScript().execute
.
Пример на vaadin
Но я не вполне уверен что это вообще надо делать в браузере. Мб Атрибуты сессии вам больше подойдут?
Мне нужно именно в локальном хранилище. Через функцию пробывал, однако, не совсем понятно что это меняет) Может можно написать скрипт, который будет добавлять токен из локального хранилища в заголовок к ответу?
Так… я не правильно понял что именно делает JavaScript.getCurrent().addFunction
В вашем случае скорее всего нужно будет создать JavaScriptComponent
Вот документация
По этой демонстрации думаю будет понятнее.
Это не совсем то. Тут описаны компоненты, которые можно делать с помощью Javascript и отрисовывать их. А мне нужно сделать, чтобы сделать следующее:
String token = //Какой-то код, который будет доставать токен из local storage.
…
// Последующая валидация и выдача authorities
…
Не обязательно там создавать компоненты и отрисовывать что-то на экране. Туда можно просто добавить функции js
чтоб вызывать их и получить от них callback
.
Не совсем понимаю каким образом, можете написать кодом, пожалуйста?
Что типа такого:
connector.js
:
com_test_extension_Component = function () {
const connector = this;
connector.getValue = function(key) {
const value = ...
connector.onValue(value)
}
}
в java
подписываетесь на onValue
и из arguments
получаете value
jsComponent.addFunction("onValue", callbackEvent -> callbackEvent.arguments ...)
при надобности вызываете функцию getValue
jsComponent.callFunction("getValue", key)
Спасибо, я получил значение из локального хранилища, но из-за того, что вызов функции js асинхронный, то я не могу записать значение в переменную для последующей проверки. Знаешь как это можно решить?
Пример:
@Subscribe(“showValueBtn”)
protected void onShowValueBtnClick(Button.ClickEvent event) throws InterruptedException {
AtomicReference token = new AtomicReference<>("");
timePicker.addFunction(“onValue”, javaScriptCallbackEvent → {
token.set(javaScriptCallbackEvent.getArguments().get(0).asString()); // здесь возвращается значение из localStorage
});
timePicker.callFunction(“getValue”);
System.out.println(token.get().toString()); // здесь всегда "", потому что функция onValue вызывается асинхронно.
}
Делать таймауты не вариант.
Лично я не знаю как сделать так, чтоб это работало синхронно. Да и навряд ли выйдет. Все таки сервер и браузер живут в разных потоках.
Если вам нужно дождаться значения с браузера. То мб создать Фоновую задачу?
То есть перед callFunction
вы создаете таску dialogs.createBackgroundWorkDialog
как бы показывая пользователю что идет загрузка данных, а в timePicker.addFunction
после получения данных эту таску отменяете.