JSF 1.2 NavigationHandler自定义导航
我试图在JSF1.2中扩展NavigationHandler,并保留一个访问页面的堆栈(更准确地说,是视图ID,以及操作和输出) 我尝试实现一个自定义操作,例如“go_back”,它将带我回到上一页 我当前的NavigationHandler:JSF 1.2 NavigationHandler自定义导航,jsf,navigation,navigationcontroller,faces-config,Jsf,Navigation,Navigationcontroller,Faces Config,我试图在JSF1.2中扩展NavigationHandler,并保留一个访问页面的堆栈(更准确地说,是视图ID,以及操作和输出) 我尝试实现一个自定义操作,例如“go_back”,它将带我回到上一页 我当前的NavigationHandler: import javax.faces.application.NavigationHandler; import javax.faces.context.FacesContext; import java.util.Stack; public clas
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只是一个简单的类,包含actionName、actionMethod和ViewId的3个字符串
我的导航规则,在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>
子页索引
/index.jsp
我到你1
/page_a1.jsp
至第2页
/page_a2.jsp
摘自a1页
/page_a1.jsp
至第2页
/page_a2.jsp
摘自a2页
/page_a2.jsp
至第1页
/page_a1.jsp
托福指数
/index.jsp
我只有3个页面,index.jsp、page_a1.jsp和page_a2.jsp
您可以在导航案例中看到它们之间的连接。我想要的是能够从pagea2.jsp“返回”到pagea1.jsp或index.jsp
正常导航工作正常:Index->P1->P2->P1->P2->Index;没问题
如果我这样做:索引->P1->P2
我将在堆栈上添加:底部
1:index.jsp/i_to_1->page_a1.jsp
2:page_a1.jsp/to_page_a2->page_a2.jsp
顶 当我尝试从P2“返回”时,我希望它返回到第1页。没有(页面刚刚重新加载)。 如果我再试一次,它就会起作用 我想这是因为在第一次尝试时,我从堆栈中弹出,它尝试使用“to_page_a2”操作失败。 第二次,它再次从堆栈中弹出,但现在它尝试使用“i_to_1”,这。。不知怎的,它起作用了 有人能帮我吗?我希望我的解释足够清楚——如果不清楚,请询问 任何类似的想法都是受欢迎的。我应该提到的是,我是在两天前开始使用JSF的,我不太清楚那里发生了什么 谢谢,,
Alex好的,我已经找到了一个解决方案(或者更好地说,一个补丁,因为我不确定它是否工作得太好) 在我做“返回”之前,我弹出两个项目,而不是一个 例如:索引->P1->P2-返回;我应该去P1(P2->P1) 为了能够到达P1,我实际上必须去“索引”点,然后尝试去P1。(在我想返回的页面之前,我必须执行一个步骤): 堆栈:
1:pop P1(我想使用它,所以我不能使用它;我只是将它从堆栈中移除)
2:pop索引-使用索引点转到P1(即使am实际上在P2中) 更新代码:
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)) {//"go_back" is the action that triggers the back move
if (trailPointStack.size() == 1) {
//It is the first page we visit (the second page in stack)
point = (NavigationPoint) trailPointStack.pop();
currentAction = null;
currentMethod = point.getActionMethod();
} else {
trailPointStack.pop();//we get rid of the prev, and we go from prev-prev to prev :D
point = (NavigationPoint) trailPointStack.pop();//actually the second one in the stack
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 max 10 items
while (trailPointStack.size() > 10) {
trailPointStack.removeElementAt(0);
}
_base.handleNavigation(fc, currentMethod, currentAction);
}
}
我希望这对别人有帮助
此外,我相信这可能不是很好,我还没有测试太多
欢迎提出任何其他想法
谢谢Alex我实现了类似的功能; 我还截取了javascript中的“backspace”键,以便单击一个隐藏的commandLink,该链接触发到堆栈中上一个视图的导航(或您需要的任何组合/逻辑) 在我的用例中,我将导航用例的逻辑展平,以便在代码中更轻松地从一点导航到另一点:
public static void navigate(String action, String outcome) {
FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, action, outcome);
}