有没有一种简单的方法在JSF中实现路由?

时间:2015-01-12 16:13:38

标签: jsf jsf-2 url-routing url-redirection

我正在尝试实现一个“通用”视图,其中显示的内容(部分)取决于URL。 E.g。

如果/somepath/somepage.xhtml指向非现有文件,而不是直接转到404错误,我想尝试使用通用视图{{1}从数据库中检索/somepath/somepage.xhtml的内容我有类似的东西:

/genericview.xhtml

,如果由支持bean找到,将从<h:outputText value="#{genericViewBean.content_lg}" escape="false" /> 表输出数据库条目的内容,具体取决于最初请求的viewId:

tgenericcontent

如果在该表中未找到视图内容,则将返回标准404错误。

我最接近克隆 webpath | content /somepath/somepage.xhtml | <p>This is a test</p> /someotherpath/someotherpage.xhtml | <p>A different test</p> 只更改文件路径(例如,更改为/genericview.xhtml)。但是这给了我一个每个视图的文件的精确副本,它非常混乱,并且它不允许我仅通过向我的数据库添加条目来创建新的URL。

如何在不克隆/somepath/somepage.xhtml的情况下获得相同的结果?

(P.S:我读过关于漂亮的脸,但是有没有更简单的解决方案?)

1 个答案:

答案 0 :(得分:9)

为此,通常使用servlet filterPrettyFacesUrlRewriteFilterFacesViews也是这样做的。

您可以通过HttpServletRequest#getRequestURI()获取请求URI。您可以通过ServletContext#getResource()检查是否存在Web资源,该资源将在不存在的资源上返回null。如果资源存在,只需按FilterChain#doFilter()继续请求,否则通过RequestDispatcher#forward()将请求转发到通用视图。

总而言之,这就是过滤器的样子:

@WebFilter("/*")
public class GenericViewFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String relativeRequestURI = request.getRequestURI().substring(request.getContextPath().length());

        boolean resourceExists = request.getServletContext().getResource(relativeRequestURI) != null;
        boolean facesResourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER));

        if (resourceExists || facesResourceRequest) {
            chain.doFilter(request, response);
        }
        else {
            request.getRequestDispatcher("/genericview.xhtml").forward(request, response);
        }
    }

    // ...
}

/genericview.xhtml中,原始请求URI可用作RequestDispatcher#FORWARD_REQUEST_URI键入的请求属性。您可以在与视图关联的支持bean的@PostConstruct中使用它,以便从数据库中提取正确的内容。

String originalRequestURI = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
// ...