Vaadin 向用户注册会话
我正在使用Vaadin8从单个模块模板开始构建一个原型。 我正试图为每个经过身份验证的用户分配一个唯一的UI实例(会话),这样每个用户都会根据自己在应用程序中的设置显示特定类型的内容。以下是我的配置:Vaadin 向用户注册会话,vaadin,vaadin8,Vaadin,Vaadin8,我正在使用Vaadin8从单个模块模板开始构建一个原型。 我正试图为每个经过身份验证的用户分配一个唯一的UI实例(会话),这样每个用户都会根据自己在应用程序中的设置显示特定类型的内容。以下是我的配置: @WebListener public class Market implements ServletContextListener { public static ArrayList<User>users; public void contextInitializ
@WebListener
public class Market implements ServletContextListener {
public static ArrayList<User>users;
public void contextInitialized(ServletContextEvent sce) {
users=new ArrayList<User>();
User hau=new User("hau");
users.add(hau);
User moc=new User("moc");
users.add(moc);
}
public void contextDestroyed(ServletContextEvent sce){}
}
public class User {
public String username;
public user(String username){this.username=username;}
}
public class MyUI extends UI {
User us3r;
@Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout();
String username;
if (this.us3r==null) {username="Guest";}else {username=us3r.username;}
Label who=new Label(username);
TextField userfield=new TextField();
Button login=new Button("login");
login.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
for (User user:Market.users) {
if (userfield.getValue().equals(user.username)) {
us3r=user;Page.getCurrent().reload();return;
}
}Notification.show("No user "+userfield.getValue());
}
});
Button logout=new Button("logout");
logout.addClickListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
if(us3r!=null) {us3r=null; Page.getCurrent().reload();}
}
});
layout.addComponent(userfield);
layout.addComponent(login);
layout.addComponent(who);
layout.addComponent(logout);
setContent(layout);
}
@WebListener
公共类市场实现了ServletContextListener{
公共静态阵列测试器;
public void contextInitialized(ServletContextEvent sce){
users=newarraylist();
用户hau=新用户(“hau”);
添加(hau);
用户moc=新用户(“moc”);
用户。添加(moc);
}
public void contextdestromed(ServletContextEvent sce){}
}
公共类用户{
公共字符串用户名;
公共用户(字符串用户名){this.username=username;}
}
公共类MyUI扩展了MyUI{
用户us3r;
@凌驾
受保护的void init(VaadinRequest VaadinRequest){
最终垂直布局=新建垂直布局();
字符串用户名;
if(this.us3r==null){username=“Guest”}else{username=us3r.username;}
Label who=新标签(用户名);
TextField userfield=新建TextField();
按钮登录=新按钮(“登录”);
login.addClickListener(新建ClickListener(){
@凌驾
公共作废按钮单击(单击事件){
for(用户:Market.users){
if(userfield.getValue().equals(user.username)){
us3r=user;Page.getCurrent().reload();return;
}
}Notification.show(“无用户”+userfield.getValue());
}
});
按钮注销=新按钮(“注销”);
logout.addClickListener(新建ClickListener(){
公共作废按钮单击(单击事件){
如果(us3r!=null){us3r=null;Page.getCurrent().reload();}
}
});
layout.addComponent(用户字段);
layout.addComponent(登录);
布局。添加组件(who);
布局。添加组件(注销);
设置内容(布局);
}
输入数据库中注册的两个用户名中的一个后,我希望Label对象显示经过身份验证的用户的名称,而不是“Guest”。我试图实现的另一个效果是,如果用户登录,并且有另一个对服务器的请求,它应该会生成一个带有未实例化us3r属性的新UI。注意:我最近一直在使用Vaadin Flow,而不是Vaadin 8。因此我的内存不清晰,我的代码可能是错误的。我将所有示例都保持得过于简单,还没有准备好生产。最后,我相信其他人会采取不同的方法,所以你可能想做一些互联网搜索,看看替代品
UI
是可延展的
Vaadin的UI
比您可能意识到的更具可塑性和可塑性。您可以使用其他包含视图的小部件完全替换初始的VerticalLayout
我使用Vaadin处理登录的方式是,我的默认UI
子类在web会话中检查我自己的User
类的对象。基于技术,每个Vaadin web应用程序都会自动受益于Servlet容器提供的基于Servlet的处理。此外,Vaadin将它们包装为
如果在会话中发现User
对象作为“属性”(键值对)存在,则我知道该用户已成功登录。因此,我在初始UI
子类对象中显示主要内容。按“主要内容”,我指的是我编写的一个特定类的实例,它扩展了VertialLayout
,或HoriontalLayout
或类似的内容
如果没有找到User
对象,那么我的初始UI
子类对象将显示一个登录视图。所谓“登录视图”,我指的是我编写的某个其他特定类的实例,该类扩展了VertialLayout
,或HoriontalLayout
或类似的内容
当您切换或变形UI
子类实例中的内容时,Vaadin负责客户端的所有更新。Java代码对服务器上UI
对象的状态所做的更改将自动传送到最初安装在web浏览器中的Vaadin JavaScript库。该VaadinJS
库通过生成所需的HTML、CSS、JavaScript等自动呈现更改后的用户界面。无需像示例代码中那样重新加载页面。。作为示例,网页只加载一次。在Vaadin中,我们基本上忘记了HTTP请求/响应周期
示例应用程序
首先,我们需要一个简单的User
类进行演示
package work.basil.example;
import java.time.Instant;
import java.util.Objects;
public class User
{
private String name;
private Instant whenAuthenticated;
public User ( String name )
{
Objects.requireNonNull( name );
if ( name.isEmpty() || name.isBlank() ) { throw new IllegalArgumentException( "The user name is empty or blank. Message # b2ec1529-47aa-47c1-9702-c2b2689753cd." ); }
this.name = name;
this.whenAuthenticated = Instant.now();
}
@Override
public boolean equals ( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
User user = ( User ) o;
return name.equals( user.name );
}
@Override
public int hashCode ( )
{
return Objects.hash( name );
}
}
我们的应用程序的起点是UI
的子类,它检查会话并切换内容。请注意,我们如何将检查和切换代码分离到一个命名方法ShowLoginOrContent
。这允许我们在登录后再次调用该代码,并在注销后再次调用该代码
package work.basil.example;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.UI;
import javax.servlet.annotation.WebServlet;
import java.util.Objects;
/**
* This UI is the application entry point. A UI may either represent a browser window
* (or tab) or some part of an HTML page where a Vaadin application is embedded.
* <p>
* The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
* overridden to add component to the user interface and initialize non-component functionality.
*/
@Theme ( "mytheme" )
public class MyUI extends UI
{
@Override
protected void init ( VaadinRequest vaadinRequest )
{
this.showLoginOrContent();
}
void showLoginOrContent ( )
{
// Check for User object in session, indicating the user is currently logged-in.
User user = VaadinSession.getCurrent().getAttribute( User.class );
if ( Objects.isNull( user ) )
{
LoginView loginView = new LoginView();
this.setContent( loginView );
} else
{
CustomerListingView customerListingView = new CustomerListingView();
this.setContent( customerListingView );
}
}
@WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
@VaadinServletConfiguration ( ui = MyUI.class, productionMode = false )
public static class MyUIServlet extends VaadinServlet
{
}
}
最后,我们需要我们的主内容视图。这里我们使用了一个尚未实际构建的“客户列表”。相反,我们放置了两段文本,以便您知道布局正在出现。请注意,在这段代码中,我们是如何从会话属性中的user
对象中查找用户名的
我们提供了一个“注销”按钮,以显示我们如何通过将用户
实例清除为会话上“属性”的值来反转身份验证。或者,您可以通过调用来终止整个会话。这取决于您的特定应用程序
package work.basil.example;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import java.time.Duration;
import java.time.Instant;
public class CustomerListingView extends VerticalLayout
{
Button logoutButton;
public CustomerListingView ( )
{
// Widgets
this.logoutButton = new Button( "Sign out" );
this.logoutButton.addClickListener( ( Button.ClickListener ) clickEvent -> {
VaadinSession.getCurrent().setAttribute( User.class , null ); // Pass null to clear the value.
( ( MyUI ) UI.getCurrent() ).showLoginOrContent();
}
);
User user = VaadinSession.getCurrent().getAttribute( User.class );
Duration duration = Duration.between( user.getWhenAuthenticated() , Instant.now() );
Label welcome = new Label( "Bonjour, " + user.getName() + ". You’ve been signed in for: " + duration.toString() + "." );
Label placeholder = new Label( "This view is under construction. A table of customers will appear here.\"" );
// Arrange
this.addComponents( this.logoutButton , welcome , placeholder );
}
}
“注销”按钮的作用是删除主要内容,并将用户带回登录视图
关注点分离
登录方法的目标之一是。构建交互式用户界面(Vaadin小部件和代码)的关注点应该与我们如何确定用户是否是他们声称的用户(auth
package work.basil.example;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import java.time.Duration;
import java.time.Instant;
public class CustomerListingView extends VerticalLayout
{
Button logoutButton;
public CustomerListingView ( )
{
// Widgets
this.logoutButton = new Button( "Sign out" );
this.logoutButton.addClickListener( ( Button.ClickListener ) clickEvent -> {
VaadinSession.getCurrent().setAttribute( User.class , null ); // Pass null to clear the value.
( ( MyUI ) UI.getCurrent() ).showLoginOrContent();
}
);
User user = VaadinSession.getCurrent().getAttribute( User.class );
Duration duration = Duration.between( user.getWhenAuthenticated() , Instant.now() );
Label welcome = new Label( "Bonjour, " + user.getName() + ". You’ve been signed in for: " + duration.toString() + "." );
Label placeholder = new Label( "This view is under construction. A table of customers will appear here.\"" );
// Arrange
this.addComponents( this.logoutButton , welcome , placeholder );
}
}