You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX中不同Controller如何传递数据?登录后userID无法跨类访问

问题原因

你遇到的问题根源有两个:

  1. WorkspaceController中直接通过new LoginController()创建的是全新的控制器实例,和处理登录逻辑的原有LoginController实例完全独立,自然无法获取到原有实例中存储的用户信息。
  2. 没有统一的载体存储登录态信息,导致跨控制器、跨DAO类无法共享用户ID数据。
解决方案

分两种实现方案,第一种是场景切换传参,适合仅需要在WorkspaceController使用用户信息的场景;第二种是全局会话存储,适合多类都需要访问登录用户信息的场景。

方案1:场景切换时传递用户数据

首先修改FactorySceneViewCreator的changeScene方法,支持加载FXML后向目标控制器传递数据:

public static void changeScene(ActionEvent event, String fxmlName, Object data) throws IOException {
    FXMLLoader loader = new FXMLLoader(FactorySceneViewCreator.class.getResource(fxmlName + ".fxml"));
    Parent root = loader.load();
    // 向目标控制器注入登录用户数据
    if (loader.getController() instanceof WorkspaceController) {
        ((WorkspaceController) loader.getController()).setCurrentProfile((Profile) data);
    }
    Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    stage.setScene(new Scene(root));
    stage.show();
}

修改LoginController登录成功后的逻辑,传入登录返回的完整用户对象:

Profile loggedInProfile = profileDataAccessObject.login(profile);
if (loggedInProfile == null) {
    System.out.println("Login failed");
} else {
    // 传递查询返回的带ID的完整用户对象
    FactorySceneViewCreator.changeScene(actionEvent, "workspace", loggedInProfile);
}

在WorkspaceController中添加接收数据的方法:

public class WorkspaceController implements Initializable {
   private Profile currentProfile;
   
   // 接收传递过来的登录用户信息
   public void setCurrentProfile(Profile profile) {
       this.currentProfile = profile;
   }

   @Override
   public void initialize(URL url, ResourceBundle resourceBundle) {
       // 可在此处直接使用currentProfile属性
       System.out.println(currentProfile);
   }
}

方案2:全局会话存储(推荐,支持全类访问)

新增单例会话上下文类,统一存储登录态,所有类均可直接访问:

// 新建SessionContext.java
public enum SessionContext {
    INSTANCE;
    
    // 存储当前登录的用户对象
    private Profile currentLoggedInProfile;
    
    public void setCurrentLoggedInProfile(Profile profile) {
        this.currentLoggedInProfile = profile;
    }
    
    public Profile getCurrentLoggedInProfile() {
        return currentLoggedInProfile;
    }
    
    // 直接获取登录用户ID,方便DAO层使用
    public Integer getCurrentUserId() {
        return currentLoggedInProfile != null ? currentLoggedInProfile.getId() : null;
    }
    
    // 退出登录时调用,清除会话数据
    public void clearSession() {
        this.currentLoggedInProfile = null;
    }
}

修改LoginController登录成功后存储会话:

Profile loggedInProfile = profileDataAccessObject.login(profile);
if (loggedInProfile == null) {
    System.out.println("Login failed");
} else {
    // 把登录用户存入全局会话
    SessionContext.INSTANCE.setCurrentLoggedInProfile(loggedInProfile);
    FactorySceneViewCreator.changeScene(actionEvent, "workspace");
}

后续任意类需要访问登录用户信息时直接调用即可:

// WorkspaceController中使用
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    Profile loggedInUser = SessionContext.INSTANCE.getCurrentLoggedInProfile();
    Integer userId = SessionContext.INSTANCE.getCurrentUserId();
    System.out.println(loggedInUser);
}

// 其他DAO类中使用
Integer currentUserId = SessionContext.INSTANCE.getCurrentUserId();
注意事项

你之前自己new的Profile对象仅包含输入的用户名和密码,需要使用profileDataAccessObject.login(profile)返回的对象,该对象才包含数据库查询得到的用户ID和其他完整属性。

内容的提问来源于stack exchange,提问作者Bantu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 20:09:00