Java EE Web应用程序中的动态目录

时间:2016-07-16 07:04:12

标签: jsf

我创建了一个使用JSF的Java EE应用程序。在我的web目录中,我有一个名为index.xhtml的文件。我的目标是根据父目录的名称在此网页上提供不同的内容。

例如:

http://localhost:8080/myapp/1/index.xhtml会打印You accessed through "1"http://localhost:8080/myapp/1234/index.xhtml会打印You accessed through "1234"

我不想为每个可能的号码创建一个目录;它应该是完全动态的。

此外,我还需要我的导航规则才能使用。所以,如果我有这样的导航规则:

<navigation-rule>
    <display-name>*</display-name>
    <from-view-id>*</from-view-id>
    <navigation-case>
        <from-outcome>index</from-outcome>
        <to-view-id>/index.xhtml</to-view-id>
        <redirect />
    </navigation-case>
</navigation-rule>

然后,如果我在目录1234中,它仍会重定向到 index.xhtml中的1234

这可能吗?我怎么能这样做?

1 个答案:

答案 0 :(得分:4)

为了将/[number]/index.xhtml转发到/index.xhtml[number]已存储为请求属性,您需要servlet filterdoFilter()实现可能如下所示:

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

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        String[] paths = request.getRequestURI().substring(request.getContextPath().length()).split("/");

        if (paths.length == 3 && paths[2].equals("index.xhtml") && paths[1].matches("[0-9]{1,9}")) {
            request.setAttribute("directory", Integer.valueOf(paths[1]));
            request.getRequestDispatcher("/index.xhtml").forward(req, res);
        }
        else {
            chain.doFilter(req, res);
        }
    }

    // ...
}

确保数字匹配1到9个拉丁数字,并将其存储为directory标识的请求属性,最后转发到上下文根目录中的/index.xhtml。如果没有任何关系,它只是继续请求,好像没有什么特别的事情发生。

/index.xhtml中,您可以按#{directory}访问该号码。

<p>You accessed through "#{directory}"</p>

然后,为了确保JSF导航(和<h:form>!)继续有效,您需要一个自定义view handler来覆盖getActionURL(),以便在URL前面添加由directory请求属性(如果有)。这是一个启动示例:

public class YourViewHandler extends ViewHandlerWrapper {

    private ViewHandler wrapped;

    public YourViewHandler(ViewHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public String getActionURL(FacesContext context, String viewId) {
        String actionURL = super.getActionURL(context, viewId);

        if (actionURL.endsWith("/index.xhtml")) {
            Integer directory = (Integer) context.getExternalContext().getRequestMap().get("directory");

            if (directory != null) {
                actionURL = actionURL.substring(0, actionURL.length() - 11) + directory + "/index.xhtml";
            }
        }

        return actionURL;
    }

    @Override
    public ViewHandler getWrapped() {
        return wrapped;
    }

}

要使其运行,请在faces-config.xml中注册,如下所示。

<application>
    <view-handler>com.example.YourViewHandler</view-handler>
</application>

这也是JSF针对诸如PrettyFaces之类的URL重写引擎的工作原理。

另见: