制作“回到上一页”系统的最佳方法是什么?

时间:2013-11-07 13:42:32

标签: jsf url jsf-2 facelets back

在我的Web应用程序中,表示层位于JSF中,我希望有按钮 某些页面上的“返回上一页”。

我是通过网址参数制作的: http://www.example.com/index.xhtml?backurl=value

例如,在mange bean中我设置了当前页面A.xhtml url:

public String showCourse(Course c){
    currentCourse = c;
    String currentUrl = FacesContext.getCurrentInstance().getViewRoot().getViewId();
    return "/B.xhtml?faces-redirect=true&backurl=" + currentUrl;
}

和B.xhtml(使用网址http://www.example.com/A.xhtml?backurl=A.xhtml) 我有

<h:button value="Back to previous page" outcome="#{backurl}"/> 

将我重定向到上一页。

一切正常,但问题是当我从B.xhtlm页面重定向到C.xhtml页面时。我再次设置backurl url参数。在转到C.xhtml页面并回到B.xhtml后我丢失了之前的backurl参数 - 当我点击按钮时我不回到A.xhtml页面而是回到C.xhtml :(

你知道为什么要这样做吗?

2 个答案:

答案 0 :(得分:1)

为什么不使用浏览器历史记录并让用户使用浏览器的后退和前进按钮?无论如何,人们几乎无法限制用户。当然,Web应用程序设计需要支持这种行为。

答案 1 :(得分:1)

虽然这很尴尬,但我有两种方法可以想到。

第一个假设是“线性流”假设,在该假设下,您有一个预定义的视图序列要呈现给用户,如在流或对话中,并且当前的后退URL取决于当前的视图ID。所以你应该有一个带有后向URL映射的应用程序作用域bean,其中键是源视图,目标视图(由后退按钮指向)将是值。然后,您可以根据当前视图ID定义后退按钮结果:

@ApplicationScoped @ManagedBean
public class BackUrlBean implements Serializable {
    private Map<String, String> map;//getter+setter
    @PostConstruct
    public void init() {
        map = new HashMap<String, String>();
        String from = ... , back = ...;
        Map.put(from, to);//fill the map
    }
}

然后,您可以在流程中拥有以下结构:

<ui:fragment rendered="#{not empty backUrlBean.map[view.viewId]}">
    <h:button value="Back to previous page" outcome="#{backUrlBean.map[view.viewId}"/>
</ui:fragment>

只要您拥有流量的线性树和预定义的一组页面,那就很好。

另一个可行的选择是传递JSON序列化的后退URL列表而不是简单的后退URL。在这种方法中,当请求下一页时,您将向列表中添加一个元素,并且用户在流程中继续前进,并且当用户单击时您将从列表中删除元素。然后最后一个列表元素是您当前的后退URL。通过Gson说明,从后到JSON序列化是在postconstruct方法中执行的。

但请注意,由于服务器的限制,获取查询参数的大小可能会受到限制,因此,如果您的流程不是很深,这种方法是可行的。此外,当您在操作方法中将其作为查询参数传递时,请不要忘记对列表进行URL编码。

这种方法的优点是它的普遍性。这种方法的实施留待您的实践。

也就是说,后退按钮必须是后退按钮,它应该将用户带到之前请求的页面。否则,您最终可能会遇到糟糕的用户体验。

在我看来,这些前后视图可以使用包含导航按钮的类似向导的组件进行模拟。具有后退按钮的方法可用于两页视图,例如主 - 细节页面,但不适用于具有更复杂结构的流程。