代码之家  ›  专栏  ›  技术社区  ›  Letholdrus

使用有状态会话作用域bean在JSF应用程序中存储用户登录信息

  •  0
  • Letholdrus  · 技术社区  · 6 年前

    很好的一天

    这个问题已经在创建MCVE时解决(感谢Kukeltje让我这样做:)

    请参阅下面的答案,了解一个有效的mcve。

    @SessionScoped
    @Stateful
    public class StoringUserInfo implements Serializable {
    
        private HashMap<String, String> userSettingMap;
        private String userName = "Test";
    
        public StoringUserInfo() {
            this.userSettingMap = new HashMap<>();
        }
    
        public void addSetting(String name, String setting) {
            userSettingMap.put(name, setting);
        }
    
        public String getSetting(String name) {
            return userSettingMap.get(name);
        }
    
        public HashMap<String, String> getUserSettingMap() {
            return userSettingMap;
        }
    
        public void setUserSettingMap(HashMap<String, String> userSettingMap) {
            this.userSettingMap = userSettingMap;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String projectName) {
            this.projectName = userName;
        }
    }
    

    例如,在一个@viewscoped@named bean中,我想这样做:

    @Named
    @ViewScoped
    public class NewProjectView implements Serializable {
    
        private static final long serialVersionUID = 1L;
        private String userName;
        @Inject private transient StoringUserInfo userInfo;
    
        public void submitForm(){
            userInfo.setUserName("NEW")
            // return to dashboard
            FacesContext.getCurrentInstance().getViewRoot().getViewMap().clear();
            PrimeFaces.current().ajax().update(":content", ":formHeader:mainMenu", ":formHeader:growl");
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
    }
    

    然后,在另一个@viewscoped@named bean上,我希望检索存储的值(由于@postconstruct获取空值,尝试取消应用程序部署中的错误)

    @Named
    @ViewScoped
    public class EditProjectView implements Serializable {
    
        private static final long serialVersionUID = 1L;
        private String userName;
        @Inject private transient StoringUserInfo userInfo;
    
    
        @PostConstruct
        public void init() {
            getValues()
        }
    
        private void getValues(){
        try {
            userName = userInfo.getUserName(); // this must display on form load
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
    }
    

    应用程序内部的工作流确保在需要值的页面之前访问设置值的页面。调试也正确地显示了这一点。

    但是,@viewscoped@命名bean始终显示为空,它们从不从@sesionscoped bean重新读取值?我这里缺什么?

    在@sessionscoped@stateful bean中为用户名字符串设置默认值将在第二个表单上显示名称“test”。

    但是,更新后的值在表单呈现/加载时永远不会被读取。因此,@postconstruct似乎只在应用程序部署时执行?

    我还将它添加到我的XHTML文件中:

    <o:form id="editProjectForm">
            <f:metadata>
                <f:viewAction action="#{editProjectView.getProjectValues}"/>
                <p:ajax update="editProjectFieldSet"/>
            </f:metadata>
            <p:fieldset id="editProjectFieldSet" legend="#{editProjectView.userName}"/>
    

    但在呈现之前,它仍然不重新查询sessionscoped bean。它只显示默认的初始值“test”

    3 回复  |  直到 6 年前
        1
  •  1
  •   Letholdrus    6 年前

    两种版本的主要区别在于:

     1. Replaced <o:form> with <h:form> 
    

    应用程序在Wildfly 14上运行,Primefaces 6.2.9和Omnifaces 3.2

        2
  •  0
  •   trulley    6 年前

    如果您正在使用CDI,请确保导入 javax.enterprise.context.sessionscoped 而不是 javax.faces.bean.sessionscoped .

        3
  •  -1
  •   Nikola Matovic    6 年前

    试试这个:

    HttpSession session = request.getSession();
    

    因此,您可以请求一个具有以下名称的参数:

    String email = (String) session.getAttribute("emailsession");