【问题标题】:Vaadin ThreadLocal for User Management用于用户管理的 Vaadin ThreadLocal
【发布时间】:2018-05-31 11:33:25
【问题描述】:

我目前正在用 Java 开发一个 Web 应用程序,该应用程序将由多个用户同时访问,因此需要存储用户数据以便根据他们的个人需求(例如他们所属的公司)来定制应用程序ETC)。

我使用 2 个类来管理它。用户,MainSystem 详述如下:

用户

@Entity
public class User implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;
    private String username;
    private String password;
    private String type;
    private String company;
    private String DOB;
    private String email;
    private int PayrollId;

    public User(String firstName, String lastName, String username, String password, String type, String company, String DOB, String email) {
        this.firstName = firstName;
        this. lastName = lastName;
        this.username = username;
        this.password = password;
        this.type = type;
        this.company = company;
        this.DOB = DOB;
        this.email = email;
    }

主系统:

public class MainSystem   {

    public UserController userController;
    private UserRepository userRepository;
    private static ThreadLocal<User> loggedInUser = new ThreadLocal<>();
    public DbController dbController;


public MainSystem(){
userController = new UserController(userRepository);
loggedInUser.set(new User());
}

 public Boolean Login(String username, String password) {
        if(userController.checkUser(username,password)){
            User aUser = userController.getUser(username);
            setLoggedInUser(userController.getUser(username));
            VaadinSession.getCurrent().setAttribute("username",loggedInUser.get().getUsername());
            System.out.println("Logged in User:  "+loggedInUser.get().getUsername());
               return true;
        }
        else {
            return false;
        }
        }

        public static void setLoggedInUser(User user){
        loggedInUser.set(user);
        }

    public static User  getLoggedInUser() {
        return loggedInUser.get();
    }

理想情况下,我想做的是从另一个类访问 ThreadLocal 变量,例如 ViewProfile.View:

public class EditProfileView extends VerticalLayout implements View {

    MainSystem main = new MainSystem();
    NavigatorUI aUI = new NavigatorUI();
    User aUser = main.getLoggedInUser();
    TextField username = new TextField("Username");
    TextField Id = new TextField("Id");
    TextField email = new TextField("Email");
    TextField firstName = new TextField("First name");
    TextField lastName = new TextField("Last name");
    TextField type = new TextField("Type");
    PasswordField oldPassword = new PasswordField("Current Password");
    PasswordField changePassword1 = new PasswordField("New Password");
    PasswordField changePassword2 = new PasswordField("Confirm Password");
    private UserController userController;
    private UserRepository userRepository;

    public EditProfileView() {
        setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
        userController = new UserController(userRepository);
     setStyleName("backgroundImage");
     setMargin(true);
     setSizeFull();
     addComponent(aUI.getHeader());
     FormLayout content = new FormLayout(generateInfo());
     Panel aPanel = new Panel("Edit User",content);
     aPanel.setWidthUndefined();
    content.setMargin(true);
    aPanel.setStyleName(ValoTheme.PANEL_WELL);
    addComponent(aPanel);
    }
 @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
       try {
           aUser = main.getLoggedInUser();
        System.out.println( aUser.getUsername());
        Id.setValue(aUser.getId().toString());
        username.setValue(aUser.getUsername());
        firstName.setValue(aUser.getFirstName());
        lastName.setValue(aUser.getLastName());
        type.setValue(aUser.getType());
        email.setValue(aUser.getEmail());
        aUI.setUserMenu();
        aUI.refreshPayroll();}
        catch (Exception e){
           System.out.println(e.getMessage());
        }
    }}

但是,我发现它向我展示了一个“空”值?我担心我可能误解了 ThreadLocal 的工作原理。但基本上我想要实现的是在 MainSystem 中存储 User.Class 的实例相关变量以供其他类使用?

任何帮助将不胜感激。

我的解决方案:

我对此的解决方案是将 User.class 存储在 VaadinSession 属性中,如下所示:

public Boolean Login(String username, String password) {
        if(userController.checkUser(username,password)){
            User aUser = userController.getUser(username);
            VaadinSession.getCurrent().setAttribute("user",aUser);
                          VaadinSession.getCurrent().setAttribute("username",loggedInUser.get().getUsername());
            System.out.println("Logged in User:  "+loggedInUser.get().getUsername());
               return true;
        }
        else {
            return false;
        }
        }

然后在其他类中,如果我想使用该属性,我会像这样检索它:

@Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
       try {
           aUser = (User)VaadinSession.getCurrent().getAttribute("user");
       }
        catch (Exception e){
           System.out.println(e.getMessage());
        }
    }

【问题讨论】:

    标签: java vaadin thread-local


    【解决方案1】:

    问题是不能保证MainSystem.Login()EditProfileView.enter() 会发生在同一个线程上。每个用户操作都作为单独的 HTTP 请求进行处理,servlet 容器将在任何可用线程上运行。

    对于这种功能,我建议将用户信息存储在 HTTP 会话中。如果您没有任何自定义 servlet 等,则可以改为在您自己的自定义 UI 类中包含一个包含用户对象的字段。 Vaadin 负责使 UI.getCurrent() 在通过 Vaadin 运行的所有代码中始终返回正确的值。

    如果您还与其他 servlet 功能集成,则可以将用户存储在 HttpSession 中。通用 servlet 代码可以通过 getSession() 方法找到会话,例如servlet 请求和响应。在 Vaadin 运行的代码中,您可以使用 VaadinSession().getCurrent().getSession() 获取基于相同 HttpSession 数据的 WrappedSession 实例。

    【讨论】:

    • 所以在 UI 类中,如果我存储了类似于普通变量的内容,即 loggedInUser = setLoggedInUser(userController.getUser(username));那么我可以只使用 VaadinSession().getCurrent().getLoggedInUser() 吗?实施情况如何?
    • 如果您向 UI 类添加实例字段并为该字段添加 getter,那么您可以执行 User loggedInUser = ((MyUI) UI.getCurrent()).getLoggedInUser(); 之类的操作
    • 我将把你的答案标记为正确,这不是我使用的那个,但它确实让我走上了正确的轨道,并且确实符合标准。
    【解决方案2】:

    还有另一种方法。相反,可以创建@SessionScoped 用户服务,以及@Inject 或@Autowire,这取决于您使用的是CDI 还是Spring。这样做时,将由 bean 管理器负责将正确的实体与您的视图绑定。

    【讨论】:

      猜你喜欢
      • 2022-01-03
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 2011-06-04
      相关资源
      最近更新 更多