我创建了一个使用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
页。
这可能吗?我怎么能这样做?
答案 0 :(得分:4)
为了将/[number]/index.xhtml
转发到/index.xhtml
,[number]
已存储为请求属性,您需要servlet filter。 doFilter()
实现可能如下所示:
@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重写引擎的工作原理。