Java JSF/Primefaces - 命令按钮:在没有 ViewScoped bean 被杀死的情况下打开新的浏览器选项卡

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18592697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:20:04  来源:igfitidea点击:

JSF/Primefaces - CommandButton: open new browser tab without ViewScoped bean getting killed

javajsfjsf-2primefacesliferay

提问by MarcelK

I'm trying to open a new browser tab with a JSF view (in a portlet, deployed in Liferay) from within a view backed by a ViewScopedbean. Using a normal action redirect kills the bean. I've tried the method provided hereand here, but unfortunately without success.

我正在尝试从ViewScopedbean支持的视图中打开一个带有 JSF 视图(在 portlet 中,部署在 Liferay 中)的新浏览器选项卡。使用正常动作重定向会杀死 bean。我已经尝试了此处此处提供的方法,但不幸的是没有成功。

The button looks more or less like this:

按钮看起来或多或少是这样的:

<p:commandButton value="#{msg.label}" onclick="target='_blank'" 
                 action="#{sessionScopedBean.action(param)}" ajax="false" />

Moving the target='_blank'to the form attribute did not help. I've tried both returning nulland voidwith no success. Changing ajax to truebroke the navigation, didn't open a new tab but also did not kill the ViewScopedbean.

移动target='_blank'到表单属性没有帮助。我都试过回国nullvoid没有成功。更改 ajax 以true破坏导航,没有打开新标签页也没有杀死ViewScopedbean。

The actionmethod content looks like this:

action方法内容如下:

public void action(String param) throws IOException {
   //some business logic

   FacesContext.getCurrentInstance().getExternalContext().redirect("viewName.xhtml");
}

The view does not contain tag handlers like <c:if test="...">or <ui:include src="...">. It did contain a <ui:repeat id="..." value="#{viewScopedBean.collection}" var="..." varStatus="...">tag, but removing it changed noting. The form is enclosed in <ui:composition>and <ui:define>tags.

该视图不包含像<c:if test="...">或 之类的标记处理程序<ui:include src="...">。它确实包含一个<ui:repeat id="..." value="#{viewScopedBean.collection}" var="..." varStatus="...">标签,但删除它改变了注意。表单包含在<ui:composition><ui:define>标签中。

The view I redirect to has no connection with the ViewScoped bean. Any ideas? :)

我重定向到的视图与 ViewScoped bean 没有任何关系。有任何想法吗?:)

采纳答案by BalusC

The view scope broke because you're with the redirect action basically instructing the client to fire a brand new GET request on the given URL. You should instead be returning nullor voidand conditionally render the results in the sameview.

视图范围中断,因为您使用重定向操作基本上指示客户端在给定的 URL 上触发全新的 GET 请求。相反,您应该返回nullvoid并有条件地在同一视图中呈现结果。

See also:

也可以看看:



The solution was already given in the links you found: put the data of interest in the flash scope before redirect and obtain them from the flash scope in the bean associated with target view. If this isn't working for you for some reason, an alternative would be to generate an unique key (java.util.UUIDmaybe?) and store it in the session scope as key associated with some data you'd like to retain in the redirected request,

您找到的链接中已经给出了解决方案:在重定向之前将感兴趣的数据放在 flash 作用域中,并从与目标视图关联的 bean 中的 flash 作用域中获取它们。如果由于某种原因这对您不起作用,另一种方法是生成一个唯一密钥(java.util.UUID也许?)并将其存储在会话范围中作为与您希望在重定向请求中保留的某些数据相关联的密钥,

String key = UUID.randomUUID().toString();
externalContext.getSessionMap().put(key, data);

and then pass that key along as request parameter in the redirect URL

然后将该键作为重定向 URL 中的请求参数传递

externalContext.redirect("nextview.xhtml?key=" + key);

so that you can in the postconstruct of the bean associated with the target view obtain the data:

以便您可以在与目标视图关联的 bean 的 postconstruct 中获取数据:

String key = externalContext.getRequestParameterMap().get("key");
Data data = (Data) externalContext.getSessionMap().remove(key);
// ...