Session 在组件中使用父类中的会话对象

Session 在组件中使用父类中的会话对象,session,object,components,tapestry,Session,Object,Components,Tapestry,在与tapestry 5的战斗中,我创建了一些不起作用的设置,我不知道为什么。我发现几乎没有解决办法,但我仍然想知道最初的想法失败的原因 我有一个父抽象页面类,具有应用程序范围的身份验证过程: public abstract class AuthPage { @SessionState protected UserAuth user; public Object onActivate(){ if(user==null) retu

在与tapestry 5的战斗中,我创建了一些不起作用的设置,我不知道为什么。我发现几乎没有解决办法,但我仍然想知道最初的想法失败的原因

我有一个父抽象页面类,具有应用程序范围的身份验证过程:

public abstract class AuthPage {
    @SessionState
    protected UserAuth user;


    public Object onActivate(){
        if(user==null)
            return LoginForm.class;
        else if(user.getLoggedIn().equals(Boolean.FALSE))
            return LoginForm.class;
        else
            return null;
    }
}
然后我有一个索引页类,使用auth类作为代理:

public class Index extends AuthPage
{

}
这部分工作得很好-当初始化用户SSO时,我得到了索引内容,否则它将转到LoginForm。现在有问题的部分索引使用了一个布局组件,它负责显示个性化的标题和菜单。其逻辑如下:

public class Layout extends AuthPage
{  
    @Property
    private Boolean loggedIn;

    @Property
    private String userName;

    @SetupRender
    public boolean checkNames(){
        if(user==null){
            loggedIn = false;
            userName = "unlogged";
        }
        else if(user.getLoggedIn().equals(Boolean.FALSE)){
            loggedIn=false;
            userName = "unlogged";
        }
        else{
            loggedIn = true;
            userName = this.user.getUsername();
        }

        return true;
    }
}
这个想法很简单——AuthPage中的session对象用户应该可以在布局中使用,并在setup render stage上使用它来获取用户名,并为呈现菜单升起标记等。从我的观点来看,一切都应该工作,但实际上Layout类并没有从session中获取用户对象(尽管它确实被初始化了,因为索引呈现了它的内容)

所以我的问题是-为什么Layout类看不到存储在会话中的UserAuth对象,而是将其获取为null

************小更新:

我已将布局重构为该形状:

public class Layout
{
    @SessionState
    protected UserAuth user;

    @Property
    private Boolean loggedIn;

    @Property
    private String userName;

    @SetupRender
    public boolean checkNames(){
        if(user==null){
             loggedIn = false;
             userName = "unlogged";
        }
        else if(user.getLoggedIn().equals(Boolean.FALSE)){
             loggedIn=false;
             userName = "unlogged";
        }
        else{
             loggedIn = true;
             userName = this.user.getUsername();
        }

        return true;
    }
}

它可以按照我的意愿工作-Layout(从索引页中的executet作为组件)从会话中获取用户属性,执行检查名并正确设置所有属性。对我来说,初始实现和第二个实现在技术上没有区别,但不知怎的,当在父类中定义用户时,总是将其设置为null(无论会话中存储了什么)。问题是-为什么它会这样工作?

布局是一个组件,而不是一个页面,而onActivate()是页面事件,当布局组件呈现时不会触发。对于组件(布局)扩展页面(AuthPage)来说没有意义。我很惊讶Tapestry允许它说出真相

另一方面,Tapestry有很多特性(包括过滤器、类转换和混合),因此几乎不需要继承。虽然非常复杂,但您可能会发现位于底部的图表很有用。您可能特别对ComponentRequestFilters和PageRenderRequestFilters感兴趣

以下是保护页面的几个选项:

  • -霍华德是Tapestry的创造者

  • 您使用的tapestry版本是什么?在tapestry 5.3.1和更早版本中,实例变量必须是私有的。只有5.3.2+版本支持受保护和包私有


    好的,我解决了问题!答案对我来说有点出乎意料,但现在一切似乎都正常了。诀窍是我引用AuthPage类的用户属性的方式。我使用了

    this.user
    
    从子类引用它。事实证明,我在任何地方都将它设为null,即使在页面中也是如此(我觉得它在索引页面中工作正常,但实际上它只是在AuthPage类中使用的)。解决方案是通过以下方式引用:

    super.user
    

    当我突然切换到这种引用样式时,每个页面和组件都开始正常工作,并从会话中获得了正确的值。我会照原样去做,但如果有人知道为什么它是这样工作的,而不是其他方式,我会很感激与我分享这些知识。

    不是那样的。我知道布局不是一个页面,我是n我不指望它在AuthPage的Activate方法上运行。我只希望它有UserAuth会话对象(作为AuthPage的扩展应该有)。Layout应该做的一切都包括在Layout.checkNames()中,但它的工作原理类似于父类的用户属性从会话中分离它是从会话中正确初始化的。我只是不明白为什么在父类中定义UserAuth对象时它不起作用。AuthPage在
    basepackage.pages.*
    package中吗?如果是,可能会混淆tapestry。组件不应该扩展页面。这不是问题。我已经移动了AuthPage(到项目的根包,到页面和组件的外部包,甚至我把它放在和布局相同的包中)但结果是AuthPage中的同一会话对象对于索引页正确初始化,对于布局组件为null。您说您将其放入组件中,并放入布局的同一个包中。布局在哪个包中?我假设它在组件(或组件的子包)中。是的。关于结构,我的项目简单而正确(可以工作,等等)。索引页在页面中,布局组件在组件中,AuthPage超类在页面中(但也在其他包中,并且不起作用)。我认为整个问题更多的是通过组件处理父类属性(至少在会话存储方面)在项目结构上。我有Tapestry 5.3.2,所以不应该是这种情况。是只有“this.user”失败了?还是“user”也失败了?Tapestry使用字节码操作将所有实例字段引用切换到getter。看起来它可能遗漏了“this.user”和“user”失败。你能试着设置为false然后再试一次吗?我认为它应该在开发模式下工作。如果我们理解这个问题,它有助于提交更好的jira问题。好的,我会在不久的将来尝试测试它,如果我发现了什么,我会发布结果。