假设我在JSF Managed Bean中有这个动作:
public String doSomething() {
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("msg", "Something was done successfully");
return "view?faces-redirect=true";
}
我的view
有一个标识为msg
的锚元素。我希望网址具有此锚点(用于辅助功能),例如:
view.jsf#msg
或者我的FacesServlet过滤模式。
return "view#msg?faces-redirect=true";
显然无效,因为JSF(至少是mojarra)会尝试将view#msg
评估为视图。
所以我的问题是如何让JSF最终重定向到#msg
的网址。
答案 0 :(得分:10)
哦,那太讨厌了。这绝对值得JSF / Mojarra男孩的增强请求。因为JSF(至少是mojarra)会尝试将
view#msg
评估为视图
您最好的选择是在ExternalContext#redirect()
的帮助下手动发送重定向。
public void doSomething() throws IOException {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.getFlash().put("msg", "Something was done successfully");
ec.redirect("view.xhtml#msg");
}
(假设FacesServlet
已映射到*.xhtml
)
或者,您可以有条件地渲染一段JS来代替。
<ui:fragment rendered="#{not empty flash.msg}">
<script>window.location.hash = 'msg';</script>
</ui:fragment>
答案 1 :(得分:0)
您尝试构建非法网址 - 片段(#
)始终是网址的最后一部分。
return "view?faces-redirect=true#msg"
将是正确的网址。
不幸的是,片段被默认的NavigationHandler
剥离,至少在JSF 2.2中。
虽然BalusC的两个选项也有效,但我还有第三种选择。使用小补丁包裹NavigationHandler
和ViewHandler
:
public class MyViewHandler extends ViewHandlerWrapper {
public static final String REDIRECT_FRAGMENT_ATTRIBUTE = MyViewHandler.class.getSimpleName() + ".redirect.fragment";
// ... Constructor and getter snipped ...
public String getRedirectURL(final FacesContext context, final String viewId, final Map<String, List<String>> parameters, final boolean includeViewParams) {
final String redirectURL = super.getRedirectURL(context, viewId, removeNulls(parameters), includeViewParams);
final Object fragment = context.getAttributes().get(REDIRECT_FRAGMENT_ATTRIBUTE);
return fragment == null ? redirectURL : redirectURL + fragment;
}
}
public class MyNavigationHandler extends ConfigurableNavigationHandlerWrapper {
// ... Constructor and getter snipped ...
public void handleNavigation(final FacesContext context, final String fromAction, final String outcome) {
super.handleNavigation(context, fromAction,
storeFragment(context, outcome));
}
public void handleNavigation(final FacesContext context, final String fromAction, final String outcome, final String toFlowDocumentId) {
super.handleNavigation(context, fromAction,
storeFragment(context, outcome), toFlowDocumentId);
}
private static String storeFragment(final FacesContext context, final String outcome) {
if (outcome != null) {
final int hash = outcome.lastIndexOf('#');
if (hash >= 0 && hash + 1 < outcome.length() && outcome.charAt(hash + 1) != '{') {
context.getAttributes().put(MyViewHandler.REDIRECT_FRAGMENT_ATTRIBUTE, outcome.substring(hash));
return outcome.substring(0, hash);
}
}
return outcome;
}
}
(我必须为ViewHandler创建包装器,因为修复了JAVASERVERFACES-3154)