JavaFX中不同Controller如何传递数据?登录后userID无法跨类访问
问题原因
你遇到的问题根源有两个:
- WorkspaceController中直接通过
new LoginController()创建的是全新的控制器实例,和处理登录逻辑的原有LoginController实例完全独立,自然无法获取到原有实例中存储的用户信息。 - 没有统一的载体存储登录态信息,导致跨控制器、跨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
相关产品推荐
相关产品推荐

