JSF 1.2 NavigationHandler 自定义导航
我正在尝试扩展 JSF 1.2 中的 NavigationHandler,并保留访问过的页面的堆栈(更准确地说,是视图 ID,以及操作和输出)。
我尝试实现一个自定义操作,例如“go_back”,它将带我返回上一页。
我当前的NavigationHandler:
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import java.util.Stack;
public class NavigationManager extends NavigationHandler {
NavigationHandler _base;
private Stack trailPointStack;
public NavigationManager(NavigationHandler base) {
super();
_base = base;
trailPointStack = new Stack();
}
@Override
public void handleNavigation(FacesContext fc, String actionMethod, String actionName) {
NavigationPoint point;
String currentAction = actionName;
String currentMethod = actionMethod;
if (actionName.equals("go_back") && (trailPointStack.size() > 0)) {
point = (NavigationPoint) trailPointStack.pop();//better check if there is something in there
//currentAction = null;
//currentMethod = null;
currentAction = point.getAction();
currentMethod = point.getActionMethod();
fc.getViewRoot().setViewId(point.getViewId());
} else {
point = new NavigationPoint(actionName, actionMethod, fc.getViewRoot().getViewId());
trailPointStack.push(point);
}
//check stack size to be less than 6 items
while (trailPointStack.size() > 5) {
trailPointStack.removeElementAt(0);
}
_base.handleNavigation(fc, currentMethod, currentAction);
}
}
NavigationPoint 只是一个带有3 个字符串的简单类,分别用于actionName、actionMethod 和ViewId。
我的导航规则,在 faces-config.xml 中:
<navigation-rule>
<description>Index to subpages</description>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>i_to_1</from-outcome>
<to-view-id>/page_a1.jsp</to-view-id>
<redirect />
</navigation-case>
<navigation-case>
<from-outcome>to_page_a2</from-outcome>
<to-view-id>/page_a2.jsp</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<navigation-rule>
<description>From page a1</description>
<from-view-id>/page_a1.jsp</from-view-id>
<navigation-case>
<from-outcome>to_page_a2</from-outcome>
<to-view-id>/page_a2.jsp</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<navigation-rule>
<description>From page a2</description>
<from-view-id>/page_a2.jsp</from-view-id>
<navigation-case>
<from-outcome>to_page_a1</from-outcome>
<to-view-id>/page_a1.jsp</to-view-id>
<redirect />
</navigation-case>
<navigation-case>
<from-outcome>to_index</from-outcome>
<to-view-id>/index.jsp</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
我只有 3 个页面,index.jsp、page_a1.jsp 和 page_a2.jsp。
您可以在导航案例中看到它们之间的联系。我想要的是能够从 page_a2.jsp“go_back”到 page_a1.jsp 或 index.jsp。
正常导航工作正常:索引 -> P1-> P2-> P1-> P2->指数;没问题。
如果我这样做:索引-> P1-> P2
我将在堆栈上:
底部
1:index.jsp/i_to_1 -> page_a1.jsp
2:page_a1.jsp/to_page_a2-> page_a2.jsp
top
当我从 P2 尝试“go_back”时,我希望它返回到第 1 页。但事实并非如此(页面刚刚重新加载)。 如果我再尝试一次,它就会起作用。
我认为这是因为在第一次尝试时,我从堆栈中弹出,并且它尝试执行“to_page_a2”操作 - 失败。 第二次,它再次从堆栈中弹出,但现在它尝试使用“i_to_1”,而这......不知何故,有效。
谁能帮我解决这个问题吗?我希望我的解释足够清楚 - 如果不是,请询问。
任何类似的想法也受到欢迎。我应该提到的是,我是在两天前开始使用 JSF 的,而且我不太清楚那里发生的一切。
谢谢你, 亚历克斯
I am trying to extend the NavigationHandler in JSF 1.2, and to keep a stack of the visited pages (more precisely, the view-ids, along with the action and the output).
I try to implement a custom action, such as "go_back", that will take me back to the previous page.
My current NavigationHandler:
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import java.util.Stack;
public class NavigationManager extends NavigationHandler {
NavigationHandler _base;
private Stack trailPointStack;
public NavigationManager(NavigationHandler base) {
super();
_base = base;
trailPointStack = new Stack();
}
@Override
public void handleNavigation(FacesContext fc, String actionMethod, String actionName) {
NavigationPoint point;
String currentAction = actionName;
String currentMethod = actionMethod;
if (actionName.equals("go_back") && (trailPointStack.size() > 0)) {
point = (NavigationPoint) trailPointStack.pop();//better check if there is something in there
//currentAction = null;
//currentMethod = null;
currentAction = point.getAction();
currentMethod = point.getActionMethod();
fc.getViewRoot().setViewId(point.getViewId());
} else {
point = new NavigationPoint(actionName, actionMethod, fc.getViewRoot().getViewId());
trailPointStack.push(point);
}
//check stack size to be less than 6 items
while (trailPointStack.size() > 5) {
trailPointStack.removeElementAt(0);
}
_base.handleNavigation(fc, currentMethod, currentAction);
}
}
The NavigationPoint is just a simple class with 3 Strings, for the actionName, actionMethod and ViewId.
My navigation rules, in faces-config.xml:
<navigation-rule>
<description>Index to subpages</description>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>i_to_1</from-outcome>
<to-view-id>/page_a1.jsp</to-view-id>
<redirect />
</navigation-case>
<navigation-case>
<from-outcome>to_page_a2</from-outcome>
<to-view-id>/page_a2.jsp</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<navigation-rule>
<description>From page a1</description>
<from-view-id>/page_a1.jsp</from-view-id>
<navigation-case>
<from-outcome>to_page_a2</from-outcome>
<to-view-id>/page_a2.jsp</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<navigation-rule>
<description>From page a2</description>
<from-view-id>/page_a2.jsp</from-view-id>
<navigation-case>
<from-outcome>to_page_a1</from-outcome>
<to-view-id>/page_a1.jsp</to-view-id>
<redirect />
</navigation-case>
<navigation-case>
<from-outcome>to_index</from-outcome>
<to-view-id>/index.jsp</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
I only have 3 pages, index.jsp, page_a1.jsp and page_a2.jsp.
You can see in the navigation cases, the connections between them. What I want is to be able to "go_back" from page_a2.jsp, to either page_a1.jsp, or to index.jsp.
The normal navigation works fine: Index -> P1 -> P2 -> P1 -> P2 -> Index; no problem.
If I do: Index -> P1 -> P2
I will have on the stack:
bottom
1:index.jsp/i_to_1 -> page_a1.jsp
2:page_a1.jsp/to_page_a2 -> page_a2.jsp
top
When I try "go_back" from P2, I expect it to go back to page 1. It doesn't (the page is just reloaded).
If I try it a second time, it works.
I think it's because on the first try, I pop from the stack, and it tries with the action "to_page_a2" - fails.
The second time, it pops again from the stack, but now it tries with "i_to_1", and this.. somehow, works.
Can anyone help me with this? I hope my explanations were clear enough - if not, please ask.
Any similar idea is also welcome. I should mention that it was 2 days ago that I started using JSF, and it's not very clear to me all that happens there.
Thank you,
Alex
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,我找到了一个解决方案(或者,更好地说,一个补丁,因为我不确定它是否工作得很好)。
在执行“go_back”之前,我会弹出 2 个项目,而不是一个。
例如:索引 -> P1-> P2-返回;我应该去 P1 (P2 -> P1)
为了能够到达 P1,我实际上必须去“索引”点,然后尝试去 P1。 (我必须在要返回的页面之前执行一步):
堆栈:
1:弹出P1(我想访问它,所以我不能使用它;我只是将它从堆栈中删除)
2:弹出索引 - 使用索引点转到 P1(即使实际上在 P2 中)
更新的代码:
我希望这对某人有帮助!
另外,我确信这可能不会很好地工作,我还没有进行太多测试。
欢迎任何其他想法。
谢谢
亚历克斯
Ok, I have found a solution (or, better said, a patch, because I am not sure it works too well).
I am popping 2 items, instead of one, before I do the "go_back".
Ex: Index -> P1 -> P2 - go_back; I am supposed to go to P1 (P2 -> P1)
To be able to reach P1, I actually have to go the the "Index" point, and then try to go to P1. (I have to go with one step before the page I want to go back to):
The stack:
1: pop P1 (I want to get to it, so I can't use it; I just remove it from the stack)
2: pop Index - use the Index point to go to P1 (even if am actually in P2)
The updated code:
I hope this helps someone!
Also, I am sure this may not be working very well, I haven't tested too much yet.
Any other ideas are welcome.
Thanks
Alex
我已经实现了类似的东西;
我还拦截了 JavaScript 中的“退格”键,以便单击隐藏的 commandLink,该链接会触发导航到堆栈中的上一个视图(或您需要的任何组合/逻辑)。
在我的用例中,我已经扁平化了导航用例的逻辑,以便更轻松地在代码中从一个点导航到另一个点:
I've implemented something similar;
I've also intercepted the "backspace" key in javascript in order to click an hidden commandLink which triggers the navigation to the previous view in the stack (or any combination/logic that you need).
In my use case I've flattened the logic of the navigation cases in order to navigate more easily from point to point within the code: