在我与tapestry 5的战斗中,我创建了一些不起作用的设置,我不知道为什么。我发现很少有解决办法,但我仍然想知道为什么最初的想法失败了。
我有一个带有应用程序范围的auth过程的父抽象页面类:
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类作为aprent:
public class Index extends AuthPage
{
}
这部分很有用 - 当初始化用户SSO时,我获得了Index内容,否则它将转到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的会话对象用户应该在Layout中可用,并在setup-render阶段使用以获取用户名并上升渲染菜单的标志等。从我的观点来看,一切都应该有效,但是练习布局类没有从会话中获取用户对象(尽管它已被初始化,因为索引会呈现其内容)。
所以我的问题是 - 为什么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;
}
}
它可以正常工作 - 布局(作为组件从索引页面执行)从会话中获取用户属性,执行checkNames并正确设置所有属性。对我来说,初始和第二个实现之间没有技术差异,但是在父类中定义用户的某种方式总是设置为null(无论会话中存储什么)。问题是 - 为什么它会这样运作?
答案 0 :(得分:0)
布局是一个组件,而不是一个页面,onActivate()是页面事件,在布局组件呈现时不会触发该事件。对于扩展页面(AuthPage)的组件(布局)没有意义。我很惊讶Tapestry允许它说出真相。
另一方面,Tapestry有很多功能(包括过滤器,类转换和mixins),几乎总是不需要继承。虽然非常复杂,但您可能会发现this page底部的图表非常有用。特别是您可能对ComponentRequestFilters和PageRenderRequestFilters感兴趣。
以下是保护页面的几个选项:
答案 1 :(得分:0)
您使用的是哪种版本的挂毯?在tapestry 5.3.1及更早版本中,实例变量必须是私有的。只有版本5.3.2+支持protected和package private。
答案 2 :(得分:0)
好的,我解决了这个问题!答案对我来说有点意外,但很好 - 现在一切似乎都很好。诀窍是我在AuthPage类中引用用户的方式。我用了
this.user
从子类中引用它。原来我在任何地方都得到它,即使在页面中(我的印象是它在Index页面中正常工作,但事实上它只是在AuthPage类中使用)。解决方案是参考:
super.user
当我切换到这样的引用样式时,每个页面和组件都开始正常工作并从会话中获得正确的值。我会把它当作原样,但如果有人知道为什么它会这样运作而不是其他 - 我会很感激与我分享这些知识。