В моем веб-приложении Vaadin у меня типичная архитектура с входом в систему. В некоторых случаях пользователь может получить прямой доступ к некоторым ресурсам, используя фрагменты URI Vaadin (http: // example.com/#fragment).
Когда пользователь пытается получить доступ к какому-либо ресурсу, если пользователь вошел в систему, я беру из URL-адреса #FRAGMENT
и привожу его к нему.
Но если пользователь не вошел в систему, когда он входит в систему, я обычно выводил его на главную страницу, используя
getPage().open("/", "_self");
Но поскольку если я добавлю фрагмент URI, getPage().open(...)
не будет работать.
Есть ли способ перенаправить пользователя на правильный URL-адрес (URL-адрес с UriFragment в моем случае) из кода?
2 ответа
Обратите внимание, что существует фундаментальная разница в том, как навигация обрабатывается в традиционных веб-приложениях по сравнению с одностраничными приложениями, реализованными с помощью Vaadin. В традиционных веб-приложениях вы перемещаетесь по приложению, выполняя полные HTTP-запросы GET по некоторому пути (например, www.example.com/myapp/home). По каждому такому запросу выполняется полная перезагрузка страницы. Вы не можете сделать это с Vaadin, поскольку полная перезагрузка страницы означает перезагрузку набора виджетов Vaadin и перестройку макета страницы с нуля. Поэтому одностраничные приложения обычно используют фрагмент URI для целей навигации. Изменения в этом фрагменте обрабатываются исключительно клиентским кодом JavaScript. При изменении фрагмента URI браузер не будет инициировать GET-запрос.
Вот почему описанный вами подход вам не подходит. Использование Page.open(...)
откроет веб-страницу через HTTP-запрос GET, что приведет к полной перезагрузке вашего приложения Vaadin.
Решение вашей проблемы состоит в том, чтобы обрабатывать всю навигацию (включая переадресацию, зависящую от состояния) исключительно с помощью методов обработки фрагментов URI объекта Page
(или через компонент [Navigator][1]
). Перенаправление в Vaadin может быть достигнуто путем программной установки фрагмента URI с помощью Page#setUriFragment()
или Navigator#navigateTo()
, а код обработки URI (или Navigator
) позаботится обо всем остальном. Только тогда вы можете быть уверены, что ваши пользователи останутся на той же странице, даже если они будут перенаправлены на форму входа или в другое место после входа в систему.
Я хотел бы добавить к ответу Роланда и рассказать, как я это решил.
Мой UI
:
@Override
protected void init(VaadinRequest request) {
setSizeFull();
setContent(masterView);
getPage().addUriFragmentChangedListener(event -> present(event.getUriFragment()));
present(getPage().getUriFragment());
}
masterView
- это просто CustomComponent
, в котором есть раздел содержания. При нажатии на меню я просто setContent
перехожу в раздел содержимого masterView. По сути, замена середины.
present
метод:
private void present(String fragment) {
masterView.setContent(getComponentFromFragment(fragment));
}
В заключение:
private Component getComponentFromFragment(String fragment) {
if (fragment.equals(someOtherView.NAME))
return someOtherView;
return null; // null clears it out as in the welcome page
}
Важная часть - это present
в init
. Когда пользовательский интерфейс отрисовывается в первый раз и запускает инициализацию, он идет вперед и захватывает любой фрагмент URI, находящийся в браузере, и также представляет его.
Работает отлично.
Похожие вопросы
Новые вопросы
redirect
Ответ веб-сервера, который просит пользовательский агент не показывать тело ответа, а вместо этого запрашивать другой ресурс. Вопросы могут быть связаны с протоколами перенаправления, равенством каналов и типами перенаправлений.