Reputation: 511
I'm trying to create a web app via Vaadin (Vaadin Framework 8).
I read several pages of documentation but still, I have big problems concerning the structure of a Vaadin app. My problem is that I lack something about the theory behind it, and I'll try to expose my problems with a first attempt of code. I'll really appreciate anything that can help me understand how Vaadin works.
I want to create a website where a user can register, log in and log out.
The structure of the GUI of the website is an Homepage where there is something like a button or something like that to do the login if the user is not logged, and if the user is logged, instead of the login button, it should appear a logout button.
First thing, I have a class that extends UI; in that class, I set the servlet and the init()
method.
In the init()
method, I start creating a VerticalLayout()
, then a MenuBar
and a Panel
(called contentPanel). Then, I create a Navigator
. The first problem I encounter is that I understand the Navigator as a possibility of browsing between different pages; the constructor of a Navigator wants a SingleComponentContainer
, so for now, I don't know how to navigate between different web pages. For my example, in the constructor I use the Panel: new Navigator(this, contentPanel);
Then I add different View
that will then appear inside the panel. Finally, I navigate to the Welcome
page.
MyUI class:
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 class:
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 class has the same structure of Login class; there is a logout method:
private void doLogout() {
MyUI.AUTH.setUser(null);
VaadinSession.getCurrent().setAttribute("user", MyUI.AUTH.getUser());
getSession().close();
}
Another problem is: how can I dynamically add components in my layout, basing on the user status (logged or not?)
Next problem is: I didn't understand how to effectively do a logout.
I'll add complete code to facilitate any tests.
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;
}
}
Upvotes: 1
Views: 856
Reputation: 4774
I have seen many users struggling with the vaadin concept.
In short it is not a page-based framework, where you switch to a new page with each mouse click.
Instead it is more like a Swing application, where you have a single gui instance, where you add forms/poups/buttons, modify them and remove them based on user interaction. This is known as a Single-Page Application.
The Navigator is mainly used to allow the user to navigate with the backward/forward buttons of the webbrowser to the "previous" page, or bookmark specific pages.
This link provides some more detailed informations about this concept.
To answer you question: - Use a single page/nvigation - When not logged in, show a modal login popup - When the user correctly enters authentification, remove the popup and show the main content in the vertical layout - When the user logs out, remove the content from the vertical layout
For your simple use case, there is no need to work with the Navigator or Views
Upvotes: 2
Reputation: 122
I initially ran into the same issues, which got me interested in Spring and ultimately Vaadin4Spring. Check out https://github.com/peholmst/vaadin4spring/tree/master/samples/security-sample-managed even if you have no interest in using Spring. It will provide you some insight on your View Navigation and with the addition of the Vaadin4Spring Sidebar it can make it easy to control access to views and menus. I am sure permissions will be your focus soon which can be complex.
Upvotes: 1