【问题标题】:Property inside the object disappears inside the session, but not the Bean itself对象内部的属性会在会话中消失,但 Bean 本身不会
【发布时间】:2012-06-01 08:54:23
【问题描述】:

我有两条不同的路径,而这只发生在另一条路径中:

  1. SignUp.Xhtml-->SigninUpOkView-->Login.xhtml-->Welcome.xhtml-->UsersController.prepareCreateParty()--->createParty.xhtml-->UsersController.createParty()

  2. SignUp.Xhtml-->SigninUpOkView-->Login.xhtml-->Logout-->Login.xhtml-->Welcome.xhtml-->UsersController.prepareCreateParty()--->createParty.xhtml-->UsersController.createParty()

那么会发生什么:我在控制器的方法 prepareCreateParty() 中创建了一个新的派对对象,并将其插入到用户对象中,这样当用户转到 CreateParty-xhtml 页面时,派对不为空,但它仅在以防万一的情况下工作2 我在 Signin up 和 createParty 之间注销。 UserController 是 managedBean 并且 UsersController 在 SessionScoped 上。我仍然在会话中使用名称为用户的用户,并将其放在登录过滤器中。 Welcome.xhtml---->UsersController.CreateParty() 之间的情况相同,但发生了一些非常奇怪的事情。我尝试在 createParty-method 中将默认名称插入派对,在第一种情况下,即使用户对象仍然存在,它也会消失,只有用户内的派对属性为 NULL。情况二,当我注销和登录时,它仍然存在并且一切正常。什么会导致这种情况?我已经尝试了一切,我开始感到痛苦和沮丧。

在用户中:

@JoinColumn(name = "party_id", referencedColumnName = "party_id")
@ManyToOne
private Party partyId; 

在用户控制器(SessionScoped ManagedBean)中: 公共用户控制器(用户用户实体){ this.currentUser = userEntity; }

public Users getSelected() {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);


        if (currentUser == null) {

            currentUser = (Users) session.getAttribute("user");
            if(currentUser==null){
                currentUser = new Users();
                selectedItemIndex = -1;
            }


        }

public String prepareCreateParty() {

    if (currentUser == null) {
        currentUser = this.getUsersFromSession();
    }

    Party party = new Party();
    party.setName("Testing default name of the party");
    currentUser.setPartyId(party);
    return "createParty";

在 CreateParty.xhtml 页面中:

<p:row>

    <p:column> <h:outputLabel value="#{bundle.CreatePartyLabel_name}" for="name" /></p:column>
    <p:column><p:inputText id="name" value="#{usersController.selected.partyId.name}" title="#{bundle.CreatePartyTitle_name}" required="true" requiredMessage="#{bundle.CreatePartyRequiredMessage_name}"/></p:column>
    <p:column><p:tooltip for="name" showEvent="focus" hideEvent="blur" /></p:column>  
    <p:column><h:outputLabel value="&nbsp;&nbsp;"/></p:column>

</p:row> 

在 LoginFilter.doFilter() 中:

if (userPrincipal != null && session.getAttribute("user") == null) {

    UsersFacade test = new UsersFacade();
    Users userEntity = test.findByUsername(userPrincipal.getName());
    session.setAttribute("user", userEntity);
    UsersController userController = new UsersController(userEntity);// Unnecessary constructor call!!

玻璃鱼 3.1.2 莫哈拉 2.1.6 PrimeFaces 3.2 疯狂1.100%

到底是什么原因造成的,非常感谢您的帮助!我希望你能理解我的解释,即使英语是这样的。 萨米人

【问题讨论】:

  • 这真的很难弄清楚。这类错误通常可以用调试器隔离。在这两种情况下逐步调试您的代码并找出差异。
  • 我做了一个口香糖解决方案:在 prepareParty-method 中,我将聚会添加到 session 和 getSelected-method 我从那里读取它并将其添加到 currentUser 并且一切正常。公共用户 getSelected() { FacesContext facesContext = FacesContext.getCurrentInstance(); HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);派对 = (派对)session.getAttribute("派对"); if(party !=null){ currentUser.setPartyId(party); }
  • 现在我调试了它,但没有解决方案。 CurrentUser 中的 Party 属性在 createParty() 和 getSelected() 方法之间变为 null,并且这两者之间没有代码。在 xhtml-page 中,我使用了像 UsersController.selected 这样的选择方法......用户名等其他一切都还可以,因此 currentUser 对象不为空,只是在其中参与。
  • 您是否从 javax.faces.bean.SessionScoped 为您的 bean 导入了正确的会话范围?
  • 导入 javax.faces.bean.SessionScoped;是的,这是在每个 managedBean Controller 类中。

标签: java session jsf properties mojarra


【解决方案1】:

我认为这个问题是因为你最终得到了Users 对象的两个不同实例(顺便说一句,我将它重命名为User,它只代表一个用户,对吧?),一个为user在由过滤器设置的会话范围内,另一个是在注册期间设置的UserControllercurrentUser 属性。您在getSelected() 检查currentUser 是否不是null,因此毕竟没有使用过滤器设置的那个。使会话无效会清除currentUser,因此它“按预期”工作。

如果您在注册时使用sessionMap.put("user", user),那么我建议您改用

@ManagedProperty("#{user}")
private Users user; // +setter

在任何必要的地方在托管 bean 中,这样您就可以确保拥有当前登录用户的唯一且正确的实例。请注意,#{user} 不一定是@ManagedBean。 EL 只是通过属性名称扫描请求/视图/会话/应用范围。

【讨论】:

  • 是的,用户只代表一个用户。 Netbeans 说 User 是保留字,所以我将其更改为 Users。 sessionMap 与普通的 HttpSession 有何不同?我有一个托管 bean 控制器,并且选择始终代表最终的 JPA 对象/bean,如用户,因此托管对象上没有属性,除了“currentObject”内部。我从一些书或教程中读到了那个设计,有什么好东西吗?优点和缺点?你认为呢?再次感谢大家对我的帮助!
  • 顺便说一句,有什么好的例子在登录后初始化会话的最佳方式是什么?
  • 会话映射是 HTTP 会话属性的 JSF 抽象,因此您无需在 JSF 代码中导入原始的 javax.servlet(这通常被认为是不好的做法)。无论您在会话映射中放置什么,实际上都会被设置为会话属性。这同样适用于请求映射 请求属性和应用程序映射 servletcontext 属性。至于登录后初始化会话,只需将用户在会话映射sessionMap.put("user", user)。它将在过滤器中作为会话属性提供,并在 EL 中作为#{user} 提供。都是同一个实例。
  • 谢谢,我会改的。对我的“设计”有何评论? @ManagedBean(name = "usersController") (AT)SessionScoped public class UsersController 实现 Serializable { private Users currentUser; //JPA-bean private DataModel items = null; (AT)EJB 私有 com.party.sessionBeans.UsersFacade ejbFacade;私人 PaginationHelper 分页; User 里面有很多东西,所以这可能是一个沉重的记忆吞噬者?当用户在会话中时,每个属性都像 Party...
  • 您确实应该尝试将Users 中的@ManyToOne 属性最小化为仅在每个请求中使用的绝对必要的属性,例如角色和一些全局设置。假设关于List&lt;Party&gt; 的信息并非在每个请求中都是绝对必要的,然后基于每个请求/视图加载它,而不是基于@ManagedProperty("#{user}")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多