JSF Flash参数没有转移到下一个视图(浏览器URL中没有?faces-redirect = true)

时间:2014-05-08 17:55:24

标签: java jsf jsf-2 post-redirect-get view-scope

我们有一个包含命令链接的页面:

<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 >

1 个答案:

答案 0 :(得分:0)

首先,我建议您不要在同一视图中使用两个@ViewScoped bean。您可以将ResultManagerFilterHandler的功能性传递到ResultManager来实现此功能。但是,如果您想在其他bean中重用ResultManagerFilterHandler方法,只需使用普通类(不由JSF管理)并使托管bean从中扩展。

另一方面,再也不用2.1.22了。只需使用最新的2.1.x分支版本,它将与您拥有的代码完全兼容,并带来许多错误修复,特别是与闪存范围相关的修复。

faces-redirect="true"相关,请记住,Faces Servlet会在将重定向URL发送到浏览器之前对其进行处理。此参数仅表示您要执行重定向,servlet将在评估后将其删除。

另见: