ExternalContext#redirect(),includeViewParams = true

时间:2016-03-08 15:14:03

标签: jsf redirect primefaces viewparams

使用字符串形式的货币列表,如下所示。

<p:selectOneMenu id="currency"
                 value="#{currencyRateBean.currency}"
                 onchange="changeCurrency([{name: 'currency', value: this.value}]);">

    <f:selectItems var="row"
                   value="#{currencyBean.currencies}"
                   itemLabel="#{row}"
                   itemValue="#{row}"/>
</p:selectOneMenu>

沿着<p:remoteCommand>

<p:remoteCommand ignoreAutoUpdate="true"
                 name="changeCurrency"
                 partialSubmit="true"
                 process="@this"
                 update="@none"
                 action="#{currency.currencyAction}"/>

托管bean将通过上述<p:remoteCommand>传递的货币值设置为JavaScript函数的参数。

@Named
@RequestScoped
public class Currency {

    @Inject
    @HttpParam
    private String currency;

    @Inject
    private CurrencyRateBean currencyRateBean;

    public Currency() {}

    public String currencyAction() throws MalformedURLException, IOException {

        try (Scanner scanner = new Scanner(new URL("http://www.exchangerate-api.com/INR/" + currency + "/1?k=FQRxs-xT2tk-NExQj").openConnection().getInputStream(), "UTF-8");) {
            currencyRateBean.setCurrencyRate(scanner.nextBigDecimal());
            currencyRateBean.setCurrency(currency);
        } catch (UnknownHostException | ConnectException e) {}

        return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true&includeViewParams=true";
    }
}

然后,从上面的操作方法CurrencyRateBean中将提供的货币值设置为另一个会话范围的托管bean currencyAction(),最终根据viewId的当前值以及includeViewParams=true这很重要。

现在,当#{currencyRateBean.currencies}被更改为包含目前为止的字符串列表的复合对象列表时,故事会发生变化。

以下方案不适用于重要的includeViewParams=true

<p:selectOneMenu value="#{currencyRateBean.currencyHolder}">

    <f:selectItems var="row" value="#{currencyBean.currencies}"
                   itemLabel="#{row.currency}"
                   itemValue="#{row}"/>

    <p:ajax event="change"
            listener="#{currency.currencyAction}"
            partialSubmit="true"
            process="@this"
            update="@none"/>
</p:selectOneMenu>
public void currencyAction()  throws IOException {
    // ...
    FacesContext facesContext = FacesContext.getCurrentInstance();
    String viewId = facesContext.getViewRoot().getViewId();

    ExternalContext externalContext = facesContext.getExternalContext();
    externalContext.redirect(externalContext.getRequestContextPath() + viewId + "?includeViewParams=true");
}

includeViewParams=true仅用于装饰。它不会起作用。

由于listener中的<p:ajax>无法根据action <p|h:commandXxx> ExternalContext#redirect()的导航案例结果进行重定向,因此必须<p:remoteCommand>反正用了。

<p:ajax>可以在完成includeViewParams=true时使用,但这将涉及到服务器两次不必要的往返,首先将货币值设置为关联的托管bean,然后进行重定向。 / p>

如何在给出的示例中使用AirTemperature AirHumidity SoilTemperature SoilMoisture LightIntensity WindSpeed Year Month Day Hour Minute Second TimeStamp MonthCategorical 12 68 19 65 60 2 2016 1 1 0 1 1 10100 January 18 34 14 42 19 0 2016 1 1 1 1 1 10101 January 19 98 14 41 30 4 2016 1 1 2 1 1 10102 January 16 88 16 68 54 4 2016 1 1 3 1 1 10103 January 16 44 20 41 10 1 2016 1 1 4 1 1 10104 January 22 54 18 65 94 0 2016 1 1 5 1 1 10105 January 18 84 17 41 40 4 2016 1 1 6 1 1 10106 January 20 88 22 92 31 0 2016 1 1 7 1 1 10107 January 23 1 22 59 3 0 2016 1 1 8 1 1 10108 January 23 3 22 72 41 4 2016 1 1 9 1 1 10109 January 24 63 23 83 85 0 2016 1 1 10 1 1 10110 January 29 73 27 50 1 4 2016 1 1 11 1 1 10111 January 28 37 30 46 29 3 2016 1 1 12 1 1 10112 January 30 99 32 78 73 4 2016 1 1 13 1 1 10113 January 32 72 31 80 80 1 2016 1 1 14 1 1 10114 January 进行重定向?

1 个答案:

答案 0 :(得分:3)

faces-redirect=true一样,includeViewParams=true仅适用于导航结果,而不适用于传递给ExternalContext#redirect()的“普通”网址。

使用NavigationHandler#handleNavigation()

FacesContext context = FacesContext.getCurrentInstance();
String outcome = viewId + "?includeViewParams=true";
context.getApplication().getNavigationHandler().handleNavigation(context, null, outcome);

或者OmniFaces

Faces.navigate(viewId + "?includeViewParams=true");

一个可疑的替代方法是自己收集所有视图参数并将它们转换为查询字符串,这样您无论如何都可以使用ExternalContext#redirect()。 OmniFaces更容易。

Faces.redirect(viewId + "?" + Servlets.toQueryString(Faces.getViewParameterMap()));