我创建了一个使用 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
,它仍然会重定向到 1234
中的index.xhtml
页面。
这可能吗?我该怎么做?
为了将/[number]/index.xhtml
转发到/index.xhtml
,从而将[number]
存储为请求属性,您需要一个 servlet 过滤器。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>
!(继续工作,您需要一个自定义视图处理程序,该处理程序覆盖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目标URL重写引擎(如PrettyFaces(的工作方式。
另请参阅:
- 如何在 Java 中使用 servlet 过滤器来更改传入的 servlet 请求 url?
- 如何在 jsf 中创建用户友好和 SEO 友好的 url?
- 获取包含查询字符串的重写 URL