JSF2.0:重定向后如何保存视图(target=blank)
假设我有jsf表单和打印表单数据报告的按钮。按钮需要打开新页面上的数据(target=blank),但是h:button不适合,因为我需要在打开报告页面之前保存数据。因此,我使用执行保存操作的h:commandButton,然后重定向到报告页面:JSF2.0:重定向后如何保存视图(target=blank),jsf,redirect,jsf-2,target,Jsf,Redirect,Jsf 2,Target,假设我有jsf表单和打印表单数据报告的按钮。按钮需要打开新页面上的数据(target=blank),但是h:button不适合,因为我需要在打开报告页面之前保存数据。因此,我使用执行保存操作的h:commandButton,然后重定向到报告页面: <h:commandLink styleClass="reportButton" action="#{polisBean.doReportPrint}" target="_blank" id="report
<h:commandLink styleClass="reportButton" action="#{polisBean.doReportPrint}"
target="_blank" id="reportListLink">
Print report
</h:commandLink>
@ViewScoped
@Named
public class PolisBean
...
public Object doReportPrint() {
if (canEdit() && this.submit() == null) {
return null;
}
return "printReport";
}
<navigation-case>
<from-outcome>printReport</from-outcome>
<to-view-id>/polises/reportList.xhtml</to-view-id>
<redirect include-view-params="true">
<view-param>
<name>id</name>
<value>#{polis.id}</value>
</view-param>
</redirect>
</navigation-case>
打印报告
@视域
@命名
公共类菜豆
...
公共对象doReportPrint(){
if(canEdit()&&this.submit()==null){
返回null;
}
返回“打印报告”;
}
打印报告
/polises/reportList.xhtml
身份证件
#{polis.id}
实体被完美保存,新页面与报告一起打开。好。但是当我返回到初始表单页面并再次尝试保存时,视图已过期并由new构建(因为这不是回发请求,这是一个全新的JSF请求,因为我刚刚从该页面进行了重定向!)。尽管重定向是在打开第二个页面时完成的,但这并不能防止丢失所有视图范围的bean数据
我尝试了CDI中长期运行的conversationScope,但当我返回初始页面时,它抛出了“ContextNotActivieException:WELD-001303作用域类型javax.enterprise.context.conversationScope无活动上下文”异常
有人解决了这个问题吗?如何在不丢失初始数据的情况下通过重定向(到新页面)提交表单?如果有人感兴趣,我找到了解决方法。不是很漂亮,但允许重定向到“空白”页面: 在新窗口中打开链接后,收据将刷新初始页面(请参见onclick): 因此,需要完成新jsf请求的更新,而不是简单的JS刷新,它包含新创建实体的id。因此,我使用这种方法: 在doReportPrint中,我将新创建的id保存到会话:
public Object doReportPrint() {
if (canEdit() && this.submit() == null) {
return null;
}
context().getExternalContext().getSessionMap().put("justUpdatedPolisId", entity.getId());
return "printReport";
}
初始页面的刷新方式如下:
public Object doRefresh() {
Object justUpdatedPolisId = context().getExternalContext().getSessionMap().get("justUpdatedPolisId");
if (justUpdatedPolisId != null) {
entity.setId((Long)justUpdatedPolisId);
context().getExternalContext().getSessionMap().remove("justUpdatedPolisId");
return "save";
}
// If for some reasons we have not found it - moving to polises table
return "polises?faces-redirect=true";
}
保存结果将导致polis.jsf重新打开(使用faces配置导航),id将自动从entity.id附加
另一个技巧是如何从JS调用JSF操作。我试图模仿h:commandLink单击(只是复制了为链接生成的JS代码),但这不起作用,因为视图被重新创建,bean及其属性也是如此,操作根本没有被调用。因此,我使用了PrimeFaces的JS代码p:commandLink,它对我非常有用(别忘了将“更新”设置为@none,将“进程”设置为@this):
函数刷新页面(){
AjaxRequest('/KaskoCalculator/polies/polis.jsf',{formId:'polisForm',async:false,global:true,源代码:'polisForm:doRefresh',进程:'polisForm:doRefresh',更新:'@none'});
}
因此,在新窗口中保存并打开报告后,初始页面将在2秒钟内刷新。太难看,太累赘了,但对我来说很有效。可能对任何人都有帮助。我也面临同样的问题。 使用p:commandLink或目标为空的h:commandLink,打开新窗口后,初始页面支持bean数据将消失 刷新将返回到页面的初始状态,而不进行ajax更新。但是我需要在单击print命令之前保持相同的状态
public Object doReportPrint() {
if (canEdit() && this.submit() == null) {
return null;
}
context().getExternalContext().getSessionMap().put("justUpdatedPolisId", entity.getId());
return "printReport";
}
public Object doRefresh() {
Object justUpdatedPolisId = context().getExternalContext().getSessionMap().get("justUpdatedPolisId");
if (justUpdatedPolisId != null) {
entity.setId((Long)justUpdatedPolisId);
context().getExternalContext().getSessionMap().remove("justUpdatedPolisId");
return "save";
}
// If for some reasons we have not found it - moving to polises table
return "polises?faces-redirect=true";
}
<script type="text/javascript">
function refreshPage() {
PrimeFaces.ajax.AjaxRequest('/KaskoCalculator/polises/polis.jsf',{formId:'polisForm',async:false,global:true,source:'polisForm:doRefresh',process:'polisForm:doRefresh',update:'@none'});
}
</script>