https - 在 RequestScoped bean 中禁用缓存并保留敏感的表单数据
问题描述
我正在更改应用程序以使其停止被缓存,使用请求标头的缓存控制参数来实现此目的。不幸的是,每当我提交表单并按下“后退”按钮时,这都会导致“确认表单重新提交”消息,这是一个很大的不...
我一直在阅读有关 Form Resubmission 和 Post-Redirect-Get 的信息,但我仍在为此苦苦挣扎。
在大多数导航案例中,我有 2 个页面:
page1 包含表单和(提交表单后)结果,它被使用了两次。
page2 显示用户单击的结果的详细信息。
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;
}
}
解决方案
推荐阅读
- iis - IIS 反向代理到 ASP.NET Core
- elasticsearch - 如何在 7.x 版本中设置 Elastic Search 分页的确切大小?
- java - 如何修复eclipselink设置
- json - 如果使用推送填充输出,则 Thingworx 输出 JSON 错误
- c# - 无法使用来自服务器的 openssl 库处理服务器名称指示
- python - 我如何重塑这个 numpy 数组?
- angular7 - 如何在 http 获取请求和响应中使用离子加载?
- java - 是否可以使用同一个按钮的意图调用两个活动?
- nginx - 音频在 openmeeting 4.0.4 中不起作用,单击开始录制测试时它会被禁用
- flutter - 如何在 Flutter 中进行“收据验证”?