我正在尝试从ViewScoped
bean支持的视图中打开一个带有JSF视图的新浏览器选项卡(位于Liferay中部署的portlet中)。使用正常操作重定向会杀死bean。
我尝试了here和here提供的方法,但遗憾的是没有成功。
按钮看起来或多或少如下:
<p:commandButton value="#{msg.label}" onclick="target='_blank'"
action="#{sessionScopedBean.action(param)}" ajax="false" />
将target='_blank'
移动到表单属性没有帮助。我已经尝试过返回null
和void
都没有成功。将ajax更改为true
打破了导航,没有打开新标签但也没有杀死ViewScoped
bean。
action
方法内容如下所示:
public void action(String param) throws IOException {
//some business logic
FacesContext.getCurrentInstance().getExternalContext().redirect("viewName.xhtml");
}
该视图不包含<c:if test="...">
或<ui:include src="...">
等标记处理程序。它确实包含<ui:repeat id="..." value="#{viewScopedBean.collection}"
var="..." varStatus="...">
标记,但删除它会改变注意事项。
表单包含在<ui:composition>
和<ui:define>
标记中。
我重定向到的视图与ViewScoped bean没有任何关联。有任何想法吗? :)
答案 0 :(得分:3)
视图范围破裂是因为您使用重定向操作基本上指示客户端在给定的URL上触发全新的GET请求。您应该返回null
或void
并有条件地在相同视图中呈现结果。
解决方案已在您找到的链接中给出:在重定向之前将感兴趣的数据放入闪存范围,并从与目标视图关联的bean中的闪存范围中获取它们。如果由于某种原因这不适合你,另一种方法是生成一个唯一的密钥(java.util.UUID
可能?)并将其存储在会话范围内,作为与您要保留的某些数据相关联的密钥。重定向的请求,
String key = UUID.randomUUID().toString();
externalContext.getSessionMap().put(key, data);
然后将该密钥作为请求参数传递到重定向网址
externalContext.redirect("nextview.xhtml?key=" + key);
这样你就可以在与目标视图关联的bean的postconstruct中获取数据:
String key = externalContext.getRequestParameterMap().get("key");
Data data = (Data) externalContext.getSessionMap().remove(key);
// ...