Redirect 如何重新加载页面以重定向到VAADIN中的URI片段?

Redirect 如何重新加载页面以重定向到VAADIN中的URI片段?,redirect,uri,vaadin7,Redirect,Uri,Vaadin7,在我的Vaadin webapp中,我有一个带有登录的典型架构。在某些情况下,用户可以使用vaadinuri片段直接访问某些资源 当用户尝试访问某些资源时,如果用户已登录,我会从URL中获取#片段,并将其带到该URL 但是如果用户没有登录,当他登录时,我通常使用 getPage().open("/", "_self"); 但是因为如果我添加一个URI片段,getPage().open(…)不起作用 是否有任何方法可以将用户从代码重定向到正确的URL(在我的例子中是带有UriFragment的U

在我的Vaadin webapp中,我有一个带有登录的典型架构。在某些情况下,用户可以使用vaadinuri片段直接访问某些资源

当用户尝试访问某些资源时,如果用户已登录,我会从URL中获取
#片段
,并将其带到该URL

但是如果用户没有登录,当他登录时,我通常使用

getPage().open("/", "_self");
但是因为如果我添加一个URI片段,
getPage().open(…)
不起作用


是否有任何方法可以将用户从代码重定向到正确的URL(在我的例子中是带有UriFragment的URL)?

请注意,在传统web应用程序中处理导航的方式与使用Vaadin实现的单页应用程序有根本的不同。在传统的web应用程序中,您通过在某些路径(如www.example.com/myapp/home)上发出完整的HTTP GET请求来浏览应用程序。在每一个这样的请求上,执行一次完整的页面重新加载。使用Vaadin无法做到这一点,因为完整页面重新加载意味着重新加载Vaadin小部件集并从头开始重建页面布局。因此,单页应用程序通常使用URI片段进行导航。对该片段的更改仅由客户端JavaScript代码处理。当URI片段更改时,浏览器将不会产生GET请求

这就是为什么您描述的方法不适合您。使用
Page.open(…)
将通过HTTP GET请求打开网页,从而完全重新加载您的Vaadin应用程序


问题的解决方案是通过
页面
对象的URI片段处理方法(或通过
[Navigator][1]
组件)单独处理所有导航(包括依赖于状态的重定向)。通过编程方式将URI片段设置为
Page#setUriFragment()
Navigator#navigateTo()
,并让URI处理代码(或
Navigator
)处理其余部分,可以实现Vaadin中的重定向。只有这样,才能确保您的用户即使在登录后被重定向到登录表单或其他地方,也能保持在同一页面上。

我想补充罗兰的答案,并分享我是如何解决这个问题的

我的
UI

@Override
protected void init(VaadinRequest request) {

    setSizeFull();
    setContent(masterView);

    getPage().addUriFragmentChangedListener(event -> present(event.getUriFragment()));

    present(getPage().getUriFragment());
}
masterView
只是一个具有内容部分的
CustomComponent
。单击菜单时,我只需将内容设置到masterView的内容部分。基本上是把中间部分换掉

呈现
方法:

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
}
重要的部分是
init
中的
present
。当UI第一次呈现并启动init时,它会继续并获取浏览器中的URI片段,并将其显示出来

效果很好