我应该使用会话来实现搜索框吗?

时间:2014-03-19 23:29:51

标签: java session struts2

我有一个包含以下字段的搜索表单

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
   }

我想知道如果不是你的建议,实施它是否是一个好习惯?

3 个答案:

答案 0 :(得分:8)

不,我不会使用会话来实现它。使用会话有几个不便之处:

  • 它使您的应用程序有状态,这使得集群变得更难:来自给定客户端的每个请求都必须转到同一服务器,或者会话必须是持久的或复制的。您在会话中投入的内存越多,内存,存储和带宽的成本就越高
  • 由于您使用硬编码的会话密钥来存储搜索条件和项目,因此您无法在同一搜索页面上打开多个标签:它们将共享相同的条件和项目。
  • 清理会话很复杂:何时进行?如果在许多用例中应用此模式,则会在会话中最终出现大量无用数据。对于其生命周期为整个会话的数据,应该对该会话提起诉讼。不是将数据从特定页面传递到下一页。

清洁解决方案并不那么难。只需使用隐藏字段或请求参数将数据从页面传递到页面:

第一页:

<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的操作可以从请求参数中检索名称,价格和类别,并显示结果。并且没有任何内容存储在会话中。

答案 1 :(得分:0)

你应该实现这样的东西。您可以更改get方法等,但这是一种非常简单的方法。

import java.util.*;

/**
 * Created by Czipperz on 3/28/2014.
 */
public class Search {
    public static class Item {
        private String price;
        private String status;
        private String owner;

        public Item(String price, String status, String owner) {
            this.price = price;
            this.status = status;
            this.owner = owner;
        }

        public String getPrice() {
            return price;
        }

        public String getStatus() {
            return status;
        }

        public String getOwner() {
            return owner;
        }
    }

    public static class Category {
        private String name;
        private List<Item> items;

        public Category(String name, List<Item> items) {
            this.name = name;
            this.items = items;
        }

        public String getName() {
            return name;
        }

        public List<Item> getItems() {
            return items;
        }
    }

    private List<Category> categories = new ArrayList<Category>();

    //Only compatable with Java 8
    public List<Item> getItems(Category selectedCategory, String price, String status, String owner) {
        //The result array
        ArrayList<Item> result = new ArrayList<Item>();
        //Starts the stream of items (see http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
        selectedCategory.getItems().stream()
                //Filters out all that don't have the price
                .filter((i) -> i.getPrice().equalsIgnoreCase(price))
                //Filters out those that don't have the status
                .filter((i) -> i.getStatus().equalsIgnoreCase(status))
                //Filters out those that don't have the owner.
                .filter((i) -> i.getOwner().equalsIgnoreCase(owner))
                //Has each added to the result List
                .forEach((i) -> result.add(i));
        //Returns the resulting list of correct items.
        return result;


        /*
        Java 7 Version:
         */
        /*
        for(Item i : items) {
            if(i.getPrice().equalsIgnoreCase(price)) {
                if(i.getStatus().equalsIgnoreCase(status)) {
                    if(i.getOwner().equalsIgnoreCase(owner)) {
                        result.add(i);
                    }
                }
            }
        }
         */
    }

    public List<Category> getCategories() {
        return categories;
    }

    public void addCategory(Category category) {
        this.categories.add(category);
    }
}

答案 2 :(得分:0)

您建议您希望用户为该页面添加书签。你需要更持久的东西。您可以使用本地存储,如果本地存储不可用,则还原为cookie。