В моем веб-приложении Vaadin у меня типичная архитектура с входом в систему. В некоторых случаях пользователь может получить прямой доступ к некоторым ресурсам, используя фрагменты URI Vaadin (http: // example.com/#fragment).

Когда пользователь пытается получить доступ к какому-либо ресурсу, если пользователь вошел в систему, я беру из URL-адреса #FRAGMENT и привожу его к нему.

Но если пользователь не вошел в систему, когда он входит в систему, я обычно выводил его на главную страницу, используя

getPage().open("/", "_self");

Но поскольку если я добавлю фрагмент URI, getPage().open(...) не будет работать.

Есть ли способ перенаправить пользователя на правильный URL-адрес (URL-адрес с UriFragment в моем случае) из кода?

2
Rafa Romero 8 Сен 2014 в 12:24

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) позаботится обо всем остальном. Только тогда вы можете быть уверены, что ваши пользователи останутся на той же странице, даже если они будут перенаправлены на форму входа или в другое место после входа в систему.

3
Roland Krüger 8 Сен 2014 в 16:03

Я хотел бы добавить к ответу Роланда и рассказать, как я это решил.

Мой 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, находящийся в браузере, и также представляет его.

Работает отлично.

0
cbmeeks 21 Авг 2015 в 21:45