GWTP 在应用程序启动时显示默认位置,即使 url 说去其他地方

GWTP displays default place on application start even if url say to go to other place

我想知道如何更改 gwtp 行为。 当我启动 gwt 应用程序(在浏览器中输入应用程序 url)时,它总是为我显示 default place。但是当我如下输入 url 时: localhost/app#settings gwtp 应该打开 Settings,但不幸的是它显示我 Default 地方。

Url 在 Web 浏览器地址中指向 Settings 但视图来自 default 地方。

我想 gwtp 显示 url 的视图。

这是我的配置:

public class UiModule extends AbstractGinModule {
    @Override
    protected void configure() {

    bind(AppView.Binder.class).in(Singleton.class);
    bind(Footer.Binder.class).in(Singleton.class);
    bind(GatekeeperProtectedMenuPanel.Binder.class).in(Singleton.class);



    install(new GinFactoryModuleBuilder().build(MenuEntryFactory.class));

    }

public class ClientModule extends AbstractPresenterModule {
    @Override
    protected void configure() {
    bind(RestyGwtConfig.class).asEagerSingleton();

    install(new DefaultModule.Builder()//
        .defaultPlace(Routing.HOME.url)//
        .errorPlace(Routing.ERROR.url)//
        .unauthorizedPlace(Routing.LOGIN.url)//
        .tokenFormatter(RouteTokenFormatter.class).build());
    install(new AppModule());
    install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));

    bind(CurrentUser.class).in(Singleton.class);
    bind(IsAdminGatekeeper.class).in(Singleton.class);
    bind(UserLoginGatekeeper.class).in(Singleton.class);



    // Load and inject CSS resources
    bind(ResourceLoader.class).asEagerSingleton();

    }

}

public class AppModule extends AbstractPresenterModule {
    @Override
    protected void configure() {
    install(new UiModule());

    // Application Presenters

    bindPresenter(AppPresenter.class, AppPresenter.MyView.class, AppView.class, AppPresenter.MyProxy.class);
    bindPresenter(HomePresenter.class, HomePresenter.MyView.class, HomeView.class, HomePresenter.MyProxy.class);
    bindPresenter(ErrorPresenter.class, ErrorPresenter.MyView.class, ErrorView.class, ErrorPresenter.MyProxy.class);
    bindPresenter(TestPresenter.class, TestPresenter.MyView.class, TestView.class, TestPresenter.MyProxy.class);
    bindPresenter(PagePresenter.class, PagePresenter.MyView.class, PageView.class, PagePresenter.MyProxy.class);
    bindPresenter(SettingsPresenter.class, SettingsPresenter.MyView.class, SettingsView.class, SettingsPresenter.MyProxy.class);
    bindPresenter(FilesPresenter.class, FilesPresenter.MyView.class, FilesView.class, FilesPresenter.MyProxy.class);
    bindPresenter(AdminAreaPresenter.class, AdminAreaPresenter.MyView.class, AdminAreaView.class, AdminAreaPresenter.MyProxy.class);

    bindPresenter(LoginPresenter.class, LoginPresenter.MyView.class, LoginView.class, LoginPresenter.MyProxy.class);
    }
}

当我有 GateKeeper 现场主持人时会发生这种情况。

代码如下:

public class UserLoginGatekeeper extends UserLoginModel implements Gatekeeper {
    private final CurrentUser currentUser;

    @Inject
    UserLoginGatekeeper(CurrentUser currentUser) {
        this.currentUser = currentUser;
    }

    @Override
    public boolean canReveal() {
        return currentUser.isLoggedIn();
    }
}

在我的主应用程序演示器中,我对服务器执行异步调用以检查用户是否登录。如果是这样,我设置客户端变量 currentUser.setLoggedIn(true);。基于此 Gatekeeper 允许访问应用程序的受限部分。

我认为问题是我的异步调用触发得太晚了。并且 GWTP 重定向到默认位置。

这是我的应用演示代码:

public class AppPresenter extends TabContainerPresenter<AppPresenter.MyView, AppPresenter.MyProxy> implements AppUiHandlers, CurrentUserChangedHandler, AsyncCallStartHandler, AsyncCallFailHandler,
    AsyncCallSucceedHandler {

    @ProxyStandard
    public interface MyProxy extends Proxy<AppPresenter> {
    }


    public interface MyView extends TabView, HasUiHandlers<AppUiHandlers> {
    void refreshTabs();

    void setTopMessage(String string);

    void setLoginButtonVisbility(boolean isVisible);
    }


    @RequestTabs
    public static final Type<RequestTabsHandler> SLOT_REQUEST_TABS = new Type<>();

    @ChangeTab
    public static final Type<ChangeTabHandler> SLOT_CHANGE_TAB = new Type<>();


    public static final NestedSlot SLOT_TAB_CONTENT = new NestedSlot();

    private static final LoginService service = GWT.create(LoginService.class);
    private final PlaceManager placeManager;
    private final CurrentUser currentUser;

    @Inject
    AppPresenter(EventBus eventBus, MyView view, MyProxy proxy, PlaceManager placeManager, CurrentUser currentUser) {
    super(eventBus, view, proxy, SLOT_TAB_CONTENT, SLOT_REQUEST_TABS, SLOT_CHANGE_TAB, RevealType.Root);
    this.placeManager = placeManager;
    this.currentUser = currentUser;
    getView().setUiHandlers(this);
    onStart();
    }

    protected void onStart() {
    service.isCurrentUserLoggedIn(new MethodCallback<Boolean>() {
        @Override
        public void onFailure(Method method, Throwable exception) {
        MaterialToast.fireToast("Fail to check is current user logged in " + method + " " + exception.getLocalizedMessage());
        }

        @Override
        public void onSuccess(Method method, Boolean response) {
        currentUser.setLoggedIn(response);
        getView().setLoginButtonVisbility(response);
        }
    });
    };

    @ProxyEvent
    @Override
    public void onCurrentUserChanged(CurrentUserChangedEvent event) {
    getView().refreshTabs();
    }

    @ProxyEvent
    @Override
    public void onAsyncCallStart(AsyncCallStartEvent event) {
    getView().setTopMessage("Loading...");
    }

    @ProxyEvent
    @Override
    public void onAsyncCallFail(AsyncCallFailEvent event) {
    getView().setTopMessage("Oops, something went wrong...");
    }

    @ProxyEvent
    @Override
    public void onAsyncCallSucceed(AsyncCallSucceedEvent event) {
    getView().setTopMessage(null);
    }


    @Override
    public void onLogoutButtonClick() {
    service.logout(new MethodCallback<Void>() {

        @Override
        public void onFailure(Method method, Throwable exception) {
        MaterialToast.fireToast("Fail to logout " + method + " " + exception.getLocalizedMessage());
        }

        @Override
        public void onSuccess(Method method, Void response) {
        MaterialToast.fireToast("You have been Succefully logout");
        PlaceRequest request = new PlaceRequest.Builder(placeManager.getCurrentPlaceRequest()).nameToken(Routing.Url.login).build();
        placeManager.revealPlace(request);
        currentUser.setLoggedIn(false);
        getView().setLoginButtonVisbility(false);
        }

    });

    }
}

工作解决方案:

/**
 * 
 */
package pl.korbeldaniel.cms.client.gin;

import gwt.material.design.client.ui.MaterialToast;

import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.MethodCallback;

import pl.korbeldaniel.cms.client.place.Routing;
import pl.korbeldaniel.cms.client.security.CurrentUser;
import pl.korbeldaniel.cms.client.service.LoginService;

import com.google.gwt.core.shared.GWT;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.Bootstrapper;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.shared.proxy.PlaceRequest;

/**
 * @author korbeldaniel
 *
 */
public class MyBootstrapper implements Bootstrapper {
    private final PlaceManager placeManager;
    private final CurrentUser currentUser;
    private static final LoginService service = GWT.create(LoginService.class);

    @Inject
    public MyBootstrapper(PlaceManager placeManager, CurrentUser currentUser) {
    this.placeManager = placeManager;
    this.currentUser = currentUser;
    }

    @Override
    public void onBootstrap() {
    GWT.log("OnBootstrap");
    service.isCurrentUserLoggedIn(new MethodCallback<Boolean>() {
        @Override
        public void onFailure(Method method, Throwable exception) {
        MaterialToast.fireToast("Fail to check is current user logged in " + method + " " + exception.getLocalizedMessage());
        placeManager.revealErrorPlace("Fail to check is current user logged in " + method + " " + exception.getLocalizedMessage());
        }

        @Override
        public void onSuccess(Method method, Boolean response) {
        // MaterialToast.fireToast("1Current user is logged in: " +
        // response);
        currentUser.setLoggedIn(response);
        if (response == true) {
            placeManager.revealCurrentPlace();
        } else {
            placeManager.revealPlace(new PlaceRequest.Builder().nameToken(Routing.Url.login).build());
        }
        }
    });
    };

}

是的,您的后端调用是异步的,很可能 UserLoginGatekeeper 代码会在后端调用 returns 之前 运行 并且用户被重定向到默认页面。

有两种解决方案:

  1. 使用动态生成的主机页面 (index.html) 并通过后端将 javascript 变量设置为用户详细信息。您可以在自定义 Bootstraper 实现中读取用户详细信息并设置 CurrentUser

  2. 如果您不想使用动态生成的主机页面,您还可以将后端调用 isCurrentUserLoggedIn 移动到自定义 Bootstrapper 实现中,并在 onSuccess 回调显示第一页(如上面链接的 GWTP 文档)