首页 > 解决方案 > 在 RequestScoped bean 中禁用缓存并保留敏感的表单数据

问题描述

我正在更改应用程序以使其停止被缓存,使用请求标头的缓存控制参数来实现此目的。不幸的是,每当我提交表单并按下“后退”按钮时,这都会导致“确认表单重新提交”消息,这是一个很大的不...

我一直在阅读有关 Form Resubmission 和 Post-Redirect-Get 的信息,但我仍在为此苦苦挣扎。

在大多数导航案例中,我有 2 个页面:

bean 是 RequestScoped 并且从 page1 到 page2 的导航是这样的:

'''

<h:dataTable value="#{page1.resultTable}">
    <h:column>
        <h:commandLink action="#{page2.getById(resultTable.id)}">
            <h:outputText value="#{resultTable.id}"/>
        </h:commandLink>
    </h:column>

   (...)

'''

使用 PRG 后,resultTable.id在 page2 加载时变为 null。我使用 Flash Scope 解决了这个问题,但是当从 page2 返回时,page1 的问题仍然存在。

访问page2后是否有一种安全优雅的方式来保留page1的数据,记住它包含敏感信息(金融应用程序)?

所有页面都基于包含后退按钮的 template.xhtml,它们各自的 bean 都是templateInterface的实现类。我认为我可以通过在 template.xhtml 的后退按钮上使用自定义代码来使用“优雅”的解决方案,该代码将再次使用 Flash Scope 将数据加载到先前访问的 bean 中。但是,一旦我单击后退按钮,我会立即收到丢失的缓存消息。

我确实设法通过包含js“window.history.replaceState(null,null,window.location.href)”来自动刷新先前访问过的页面,但是这样做会丢失所有表单数据......这是不是有更好的解决方案?

编辑:

page1.xhtml 看起来像这样:

<?xml version='1.0' encoding='UTF-8' ?>
<ui:composition xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                template="/WEB-INF/templates/transaction-template.xhtml"
                xmlns:t="http://myfaces.apache.org/tomahawk"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:components="http://java.sun.com/jsf/composite/components">

    <ui:define name="mainContent">
        <h:form id="form">
            <h:inputHidden id="_itemId" value="#{listItem.itemId}" />

            <fieldset class="fieldsetTransaction">
                <table class="formTransaction">
                    <tr>
                        <td class="labelsCol">
                            <h:outputText value="#{labels.itemId}" />
                        </td>                        
                        <td class="valuesCol">
                             <h:inputText value="#{listItem.itemId}" />
                        </td>
                    </tr>
                    <tr>
                        <td class="labelsCol">
                            <h:outputText value="#{labels.itemName}" />
                        </td>
                        <td class="valuesCol">
                             <h:inputText value="#{listItem.itemName}" />
                        </td>
                    </tr>
                    <tr class="formActions">
                        <td colspan="4">
                            <h:commandButton value="#{labels.search}"
                                                 title="#{labels.search}"
                                                 type="submit"
                                                 id="search"
                                                 action="#{listItem.list()}"
                                                 styleClass="default formButton">
                                <f:ajax execute="@form" render="resultPanel"/>
                            </h:commandButton>
                        </td>
                    </tr>
                </table>
            </fieldset>

            <h:panelGroup id="resultPanel">
            <fieldset class="fieldsetTransaction">

                <h:dataTable value="#{listItem.listReply.itemList}"
                             cellpadding="1" id="itemList_"
                             border="0" width="100%" columnClasses="c, l, c, l"
                             rowClasses="odd, even"
                             styleClass="list" var="itemList" cellspacing="1"
                             rendered="#{not empty listItem.listReply.itemList}">
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="#{labels.itemId}" />
                        </f:facet>
                        <h:commandLink action="#{editItem.getById(itemList.itemId)}"
                                       id="searchItemLink"
                                       title="#{menu['search.item']}">
                            <h:outputText value="#{itemList.itemId}" />
                        </h:commandLink>

                         <!-- new working code -->
                        <h:link action="#{editItem.getById(itemList.itemId)}"
                                       id="searchItemLink_"
                                       title="#{menu['search.item']}">
                            <h:outputText value="#{itemList.itemId}" />
                            <f:param name = "itemId" value"#{editItem.itemId}" />
                        </h:link>
                    </h:column>
                </h:dataTable>
            </fieldset>
            </h:panelGroup>

            <t:saveState value="#{listItem.listReply}" />
        </h:form>
    </ui:define>

    <ui:define name="filename">
        item\itemManagement\list_items.xhtml
    </ui:define>
</ui:composition>

第 1 页 bean:

@Named("listItem")
@RequestScoped
public class ListItemIdsBean extends AbstractBean {

    private BigInteger itemId;
    private String itemName;

    // dummy code, just to represent irrelevant business logic that returns a list of items
    private ExtAppListReply listReply;

    public BigInteger getItemId() {
        return itemId;
    }

    public void setItemId(BigInteger itemId) {
        this.itemId = itemId;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public ExtAppListReply getExtAppTransaction() {
        if( listReply == null ) {
            listReply = new ExtAppListReply();
        }
        return listReply;
    }

    public void setExtAppTransaction(ExtAppListReply trx) {
        this.trx = trx;
    }

    private void list(BigInteger itemId, String itemName) {

        ExtAppTransaction trx = ExtAppTransactionFeeder.feeder(this, itemId, itemName);
        ExtAppListReply listReply = super.executeTransaction(trx);

        if( listReply != null && !listReply.isSetRefusalCode() ) {
            setExtAppTransaction(listReply);
        } else {
            if( !(type == BACKWARD || type == FORWARD)  ) {
                setExtAppTransaction(null);
            }
        }

        // show results in the same page
        return null;

    }

}

标签: httpsjsf-2.2

解决方案


推荐阅读