【问题标题】:Building a Vaadin web app with dynamic content构建具有动态内容的 Vaadin Web 应用程序
【发布时间】:2017-10-16 14:47:37
【问题描述】:

我正在尝试通过 Vaadin (Vaadin Framework 8) 创建一个 Web 应用程序。

我阅读了几页文档,但我仍然对 Vaadin 应用程序的结构有很大的疑问。我的问题是我缺乏关于它背后的理论的东西,我将尝试通过第一次代码尝试来暴露我的问题。任何能帮助我理解 Vaadin 工作原理的东西,我都会非常感激。

我想创建一个用户可以注册、登录和注销的网站。

网站的 GUI 结构是一个 主页,如果用户未登录,则有类似按钮或类似的东西来进行登录,如果用户已登录,而不是登录按钮,它应该出现一个注销按钮

首先,我有一个扩展UI的类;在那个类中,我设置了 servlet 和 init() 方法。

init() 方法中,我开始创建VerticalLayout(),然后是MenuBarPanel(称为contentPanel)。然后,我创建了一个Navigator。我遇到的第一个问题是,我将 Navigator 理解为一种在不同页面之间浏览的可能性; Navigator 的构造函数想要一个SingleComponentContainer,所以现在,我不知道如何在不同的网页之间导航。对于我的示例,在构造函数中我使用面板:new Navigator(this, contentPanel); 然后我添加不同的View,然后将出现在面板内。最后,我导航到Welcome 页面。

MyUI 类:

public class MyUI extends UI {

    /**
     * Class that checks if the user is in the database 
     * and the psw inserted is correct
     */
    public static Authentication AUTH;
    public static User user = null;

    @WebServlet(value = "/*", asyncSupported= true)
    @VaadinServletConfiguration(productionMode = false, ui = MyUI.class)
    public static class MyUIServlet extends VaadinServlet {
    }

    @Override
    protected void init(VaadinRequest request) {

        AUTH = new Authentication();

        VaadinSession.getCurrent().setAttribute("user", user);

        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        setContent(layout);

        Panel contentPanel = new Panel("Main Panel");
        contentPanel.setSizeFull();

        new Navigator(this, contentPanel);
        getNavigator().addView(LoginPage.NAME, LoginPage.class);
        getNavigator().setErrorView(LoginPage.class);
        getNavigator().addView(LogoutPage.NAME, LogoutPage.class);
        getNavigator().addView(WelcomePage.NAME, WelcomePage.class);

        MenuBar.Command welcome = new Command() {
            @Override
                public void menuSelected(MenuItem selectedItem) {
                    getNavigator().navigateTo(WelcomePage.NAME);
                }
        };

        MenuBar.Command login = new Command() {
            @Override
            public void menuSelected(MenuItem selectedItem) {
                getNavigator().navigateTo(LoginPage.NAME);
            }
        };

        MenuBar.Command logout = new Command() {
            @Override
            public void menuSelected(MenuItem selectedItem) {
                getNavigator().navigateTo(LogoutPage.NAME);
            }
        };

        MenuBar mainMenu = new MenuBar();
        mainMenu.addItem("Welcome", VaadinIcons.ARROW_CIRCLE_LEFT, welcome);
        mainMenu.addItem("Login", VaadinIcons.ENTER, login);
        mainMenu.addItem("Logout", VaadinIcons.EXIT, logout);

        layout.addComponent(mainMenu);
        layout.addComponent(contentPanel);

        getNavigator().navigateTo(WelcomePage.NAME);

    }

}

LoginPage 类:

public class LoginPage extends VerticalLayout implements View {

    private static final long serialVersionUID = 1L;
    public static final String NAME = "loginpage";

    public LoginPage(){

        Panel panel = new Panel("Login");
        panel.setSizeUndefined();
        addComponent(panel);

        FormLayout content = new FormLayout();
        TextField username = new TextField("Username");
        content.addComponent(username);
        PasswordField password = new PasswordField("Password");
        content.addComponent(password);

        Button send = new Button("Enter");

        send.addClickListener(new Button.ClickListener() {
            private static final long serialVersionUID = 1L;

            public void buttonClick(ClickEvent event) {

                //The authenticate method will returns
                //true if the credentials are correct
                //false otherwise
                if(MyUI.AUTH.authenticate(username.getValue(), password.getValue())){

                    //In AUTH there is a User field called "user"
                    //User is a class that represents an user (so it has mail, psw, name etc)
                    VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());

                }else{
                    Notification.show("Invalid credentials", Notification.Type.ERROR_MESSAGE);
                    }

                }
            });

        content.addComponent(send);
        content.setSizeUndefined();
        content.setMargin(true);
        panel.setContent(content);
        setComponentAlignment(panel, Alignment.MIDDLE_CENTER);

    }

}

Logout 类与Login 类结构相同;有注销方法:

private void doLogout() {

    MyUI.AUTH.setUser(null);
    VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
    getSession().close();

}

另一个问题是:如何根据用户状态(是否登录?)在布局中动态添加组件

下一个问题是:我不明白如何有效地注销。

我将添加完整的代码以方便任何测试。

public class LogoutPage extends VerticalLayout implements View {

    private static final long serialVersionUID = 1L;
    public static final String NAME = "logoutpage";

    public LogoutPage(){

        Panel panel = new Panel("Logout");
        panel.setSizeUndefined();
        addComponent(panel);

        Button logout = new Button("Logout");
        logout.addClickListener(e -> doLogout());
        addComponent(logout);

    }

    private void doLogout() {

        MyUI.AUTH.setUser(null);
        VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
        getSession().close();

    }

}

______________________________________________________________________________

public class WelcomePage extends VerticalLayout implements View {

    private static final long serialVersionUID = 1L;
    public static final String NAME = "welcomepage";

    public WelcomePage() {
        setMargin(true);
        setSpacing(true);
        Label welcome = new Label("Welcome");
        welcome.addStyleName("h1");
        addComponent(welcome);

    }

    @Override
        public void enter(ViewChangeEvent event) {
    }

}

______________________________________________________________________________

public class Authentication {

    private static User user = null;
    //those fields should be in user; this is just a test
    private String userID = "ID";
    private String psw = "psw";

    public Authentication() {
    }

    public void setUser(User user) {
        Authentication.user = user;
    }

    public User getUser(){
        return Authentication.user;
    }

    public Boolean authenticate(String userID, String psw){

        if(userID == this.userID && psw == this.psw) {
            user = new User();
            return true;
        }

        return false;

    }

}

【问题讨论】:

    标签: java vaadin vaadin8


    【解决方案1】:

    我看到很多用户都在为 vaadin 概念苦苦挣扎。

    简而言之,它不是一个基于页面的框架,您每次点击鼠标都会切换到一个新页面。

    相反,它更像是一个 Swing 应用程序,您有一个单一的 gui 实例,您可以在其中添加表单/弹出框/按钮,根据用户交互对其进行修改和删除。这被称为Single-Page Application

    导航器主要用于允许用户使用网络浏览器的后退/前进按钮导航到“上一个”页面,或为特定页面添加书签。

    This link 提供了有关此概念的一些更详细的信息。

    回答你的问题: - 使用单页/导航 - 未登录时,显示模式登录弹出窗口 - 当用户正确输入认证时,移除弹窗并以垂直布局显示主要内容 - 当用户注销时,从垂直布局中删除内容

    对于您的简单用例,无需使用导航器或视图

    【讨论】:

    • 更新: 有了 Vaadin Flow,情况发生了根本性的变化。 Flow 中的 new “Router” functionality 取代了 Vaadin 8 Navigator,可与可收藏的 URL 配合使用,为 Vaadin 单页应用程序提供网站感觉。
    【解决方案2】:

    我最初遇到了同样的问题,这让我对 Spring 以及最终对 Vaadin4Spring 产生了兴趣。看看https://github.com/peholmst/vaadin4spring/tree/master/samples/security-sample-managed,即使您对使用 Spring 没有兴趣。它将为您提供有关视图导航的一些见解,并且通过添加 Vaadin4Spring 侧边栏,它可以轻松控制对视图和菜单的访问。我相信权限很快就会成为您关注的焦点,这可能会很复杂。

    【讨论】:

      猜你喜欢
      • 2012-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      相关资源
      最近更新 更多