我们有一个包含命令链接的页面:
<h:commandLink value="Go to Result Manager"
action="#{resultManagerDashboardHelper.navigateToTargetAll()}" />
这应该重定向到结果管理器视图,秘密传递表示“TODO”和“DONE”的两个状态标志的列表,以便将过滤器设置为“所有状态”。
ResultManagerDashboardHelper.java:
@Named
@ViewScoped
public class ResultManagerDashboardHelper
{
...
public static final String SECRET_ARGS_KEY = "secretArgs";
...
private String navigateToPage( String outcome, String... args )
{
List<String> argsList = Arrays.asList( args );
FacesContext.getCurrentInstance().getExternalContext().getFlash().put( SECRET_ARGS_KEY, argsList );
String fullOutcome = outcome + "?faces-redirect=true";
System.out.println( "Setting flash secret args to " + argsList );
System.out.println( "Redirecting from '" + this.outcomeMapper.getCurrentOutcome() + "' to '" + fullOutcome + "'" );
return fullOutcome;
}
private String navigateToTargetPage( String... args )
{
return this.navigateToPage( "/view/resultmgmt/resultManager", args );
}
public String navigateToTargetAll()
{
return this.navigateToTargetPage( "TODO", "DONE" );
}
}
ResultManagerFilterHandler.java:
@Named
@ViewScoped
public class ResultManagerFilterHandler
{
...
// status flags secretly coming in via Flash from dashboard
private List<String> secretStatusFlags;
@Override
@PostConstruct
public void init()
{
...
@SuppressWarnings( "unchecked" )
List<String> secretStatusFlags = ( List<String> ) FacesContext.getCurrentInstance().getExternalContext().getFlash().get( ResultManagerDashboardHelper.SECRET_ARGS_KEY );
if ( secretStatusFlags != null )
{
System.out.println( "ResultManagerFilterHandler secret arguments have arrived via JSF Flash! Size = " + secretStatusFlags.size() );
}
else
{
System.out.println( "ResultManagerFilterHandler: NO secret arguments have arrived via JSF Flash!" );
}
// sits in view scope waiting to be picked up by search routine in ResultManager (also view-scoped)
this.secretStatusFlags = secretStatusFlags;
}
}
ResultManager.java:
@Named
@ViewScoped
public class ResultManager
{
...
@Inject
private ResultManagerFilterHandler filterHandler;
@Override
public void searchInitially()
{
// get Flash object from filter handler
List<String> statusFlags = this.getFilterHandler().getSecretStatusFlags();
System.out.println( "ResultManager statusFlags = " + statusFlags );
// if flash args have been passed, prefer that view over the standard one
if ( statusFlags != null && !statusFlags.isEmpty() )
{
System.out.println( "Flash search!" );
// set to today and decrypt the passed status flags (this is supposed to override the default search filter!)
this.filterHandler.setSelectedPeriod( EPeriod.TODAY );
this.filterHandler.calculateBeginEndDates( this.filterHandler.getSelectedPeriod() );
this.filterHandler.setTodoOnly( statusFlags.size() == 1 && statusFlags.get( 0 ).equals( "TODO" ) );
this.search();
}
else
{
System.out.println( "Non-flash search!" );
super.searchInitially();
}
}
}
单击上述链接时,浏览器将重定向到正确的视图。然后是resultManager.xhtml
页面上的活动
<f:event type="preRenderView"
listener="#{resultManager.searchInitially}" />
调用searchInitially
方法,该方法应该从ResultManagerFilterHandler
bean中获取存储的状态标志。但是Flash参数不存在:
18:58:42,840 INFO [] (134) Setting flash secret args to [TODO, DONE]
18:58:42,840 INFO [] (134) Redirecting from '/view/dashboard' to '/view/resultmgmt/resultManager?faces-redirect=true'
18:58:43,039 INFO [] (135) ResultManagerFilterHandler: NO secret arguments have arrived via JSF Flash!
18:58:44,350 INFO [] (135) ResultManager statusFlags = []
18:58:44,350 INFO [] (135) Non-flash search!
问:
我做错了什么?我如何让它工作?
请注意,?faces-redirect=true
URL参数未附加到URL ...我想知道为什么?这可能是空闪的原因吗?或者这是正常行为吗?
我们正在使用 Mojarra 2.1.22 ,众所周知,这会让Flash实例更长时间存在问题,但这是我稍后要解决的问题。
PS:对不起复杂的例子,实际上它更复杂......: - /
PPS:哦,不要介意@Named
和@ViewScoped
的组合,我们使用的是Seam 3,它将CDF @ViewScoped
替换为CDI兼容的。{/ p >
答案 0 :(得分:0)
首先,我建议您不要在同一视图中使用两个@ViewScoped
bean。您可以将ResultManagerFilterHandler
的功能性传递到ResultManager
来实现此功能。但是,如果您想在其他bean中重用ResultManagerFilterHandler
方法,只需使用普通类(不由JSF管理)并使托管bean从中扩展。
另一方面,再也不用2.1.22了。只需使用最新的2.1.x分支版本,它将与您拥有的代码完全兼容,并带来许多错误修复,特别是与闪存范围相关的修复。
与faces-redirect="true"
相关,请记住,Faces Servlet会在将重定向URL发送到浏览器之前对其进行处理。此参数仅表示您要执行重定向,servlet将在评估后将其删除。
另见: