我有一个包含以下字段的搜索表单
price, status, owner
当用户填写所有字段时,请求将发送到后端,以显示包含具有指定价格,状态和所有者的产品的类别列表。用户可以单击每个类别以查看其产品列表。
为了实现它,我有以下方法来检索类别,并将搜索字段(价格,状态,所有者)放入会话中,以便在搜索的下一页(选择类别时)可用。
参数的值可能太长,我更喜欢将它们作为GET来轻松标记结果。
public String retrieveCategories(){
//... here I retrieve categories which their products are matched
//with the search fields
Map session = ActionContext.getContext().getSession();
session.put("Items", this.items);
return "SUCCESS";
}
一旦显示了所有类别,用户便可以单击每个类别来查看其产品。
类别名称将发送到后端,因此我将从会话中检索值以搜索与所选类别具有相同规格的产品。
public String retrieveProductsOfSelectedCategory(){
Map session = ActionContext.getContext().getSession();
this.items = (Items) session.get("Items");
//... here I retrieve products of the selected category based on values retrieved
// from session
}
我想知道如果不是您的建议,实施它是否是一个好习惯?
最佳答案
不,我不会使用会话来实现这一点。使用会话有一些不便之处:
它使您的应用程序变成有状态的,这使得群集变得更加困难:来自给定客户端的每个请求都必须转到同一服务器,或者会话必须是持久的或重复的。您投入的会话越多,则在内存,存储和带宽方面的花费就越高
由于您使用硬编码的会话密钥来存储搜索条件和项目,因此无法在同一搜索页面上打开多个选项卡:它们将共享相同的条件和项目。
清理会话很复杂:什么时候做?如果将这种模式应用于许多用例,则会话中最终将获得大量无用的数据。应该使用该会话来获取其生命周期为整个会话的数据。不适用于将数据从特定页面传递到下一页。
干净的解决方案并不难。只需使用隐藏字段或请求参数即可在页面之间传递数据:
第一页:
<input type="text" name="price" />
<input type="text" name="owner" />
第二页
Please choose a category:
<ul>
<li><a href="/products?name=foo&price=12&category=first"></a></li>
<li><a href="/products?name=foo&price=12&category=second"></a></li>
<li><a href="/products?name=foo&price=12&category=third"></a></li>
</ul>
然后,映射到/ products的操作可以从请求参数中检索名称,价格和类别,并显示结果。会话中没有任何存储。