簡體   English   中英

在動作類中執行 CRUD 操作以及 Struts2 中的 prepare() 方法

[英]Performing CRUD operations in an action class along with the prepare() method in Struts2

假設有以下動作類。

@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value="struts-default")
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, Preparable
{
    private Long currentPage=1L;

    //This method is called on page load. 
    //Validation is skipped, location is set to a valid action, not "redirectAction", the request is dispatched. 
    //It is mapped to an action of <s:form>.
    public String load() throws Exception
    {
        //Nothing to see here. Leave it empty.
        return ActionSupport.SUCCESS;
    }

    //Assuming necessary validators and action whose result type is set to "redirectAction". 
    //It is mapped to an action of <s:submit>.
    public String insert()
    {
        //Do something to either add or update data in a model based on a conditional check.
        return ActionSupport.SUCCESS;
    }

    //Assuming necessary validators and action whose loction is set to a valid action. not "redirectAction". 
    //The request is dispatched/forwarded. 
    //It is mapped to an action of <s:a>.
    public String edit()
    {
        //Nothing to see here. Leave it empty.
        return ActionSupport.SUCCESS;
    }

    //Assuming necessary validators and action whose result type is set to "redirectAction". 
    //It is mapped to an action of <s:submit>.
    public String delete()
    {
        //Do something to delete data from a model.
        return ActionSupport.SUCCESS;
    }

    @Override
    public void prepare() throws Exception
    {
        list= service.getList((int)(currentPage-1)*pageSize, pageSize);
    }
}

我已經排除了注釋和其他東西以避免代碼噪音。 映射到這些方法的操作使用paramsPrepareParamsStack攔截器。

在這里,例如,當與insert()方法關聯的操作被觸發(由<s:submit> )時,結果將是重定向操作。 因此,將創建 action 類的一個新實例,這將導致執行load()方法,這又導致再次執行prepare()方法。 更新和刪除時也會發生同樣的事情。

prepare()方法在與<s:submit> (或<s:link> )相關聯的動作被觸發時首先執行,然后在請求重定向時再次執行(這可以理解,因為請求的重定向導致創建 action 類的一個新實例,它會導致執行與load()方法關聯的 action,並且prepare()在每個 action 上執行一次)。

prepare()方法中的唯一一行是代價高昂的操作。 為了防止getList()方法被執行兩次,我做了一些條件檢查,如下所示。

@Override
public void prepare() throws Exception
{
    String actionName = ActionContext.getContext().getName();
    if(actionName.equals("load")||actionName.equals("edit"))
    {
        list= service.getList((int)(currentPage-1)*pageSize, pageSize);
    }
}

在這個方法中可能有更多的條件檢查和復雜的代碼。

這樣做還是不夠的。 如果由於條件而發生任何驗證/轉換錯誤,則不會初始化列表。 hasErrors()hasActionErrors()hasFieldErrors()都不會在出現任何錯誤后在prepare()方法中被評估為真。 這需要將列表加載到validate()方法中,如下所示。

@Override
public void validate()
{
    if(hasErrors())
    {
        list= service.getList((int)(currentPage-1)*pageSize, pageSize);
    }
}

這現在滿足了要求,但是有這樣的條件檢查看起來很丑陋,不能被認為是一個好方法。

有沒有更好的方法來保證在執行插入、更新、刪除等操作的請求后,從數據庫中檢索列表只發生一次?

它應該獨立於每個請求在幕后執行的操作數。 盡管存在一些轉換/驗證錯誤,但應僅在請求完成之前檢索列表一次事件。

@Before@BeforeResult@After注釋似乎都@BeforeResult這種情況。


在用於檢索/初始化列表的validate()方法中使用此類代碼似乎不是一個好習慣。

我希望有一種方法可以CRUD 操作獲取此列表。 由於從數據庫獲取此列表的成本很高,因此該列表應僅每次操作(插入、編輯、更新、刪除)完成初始化一次。

在為每個動作執行的prepare()方法中prepare() ,諸如填充列表之類的繁重操作不是一個好方法。 因為並不是所有的動作都需要執行這樣的操作。

但是當與驗證一起使用時,根本不執行任何操作。 如果發生驗證錯誤,則返回INPUT結果。 此結果是您的用例中的dispatcher結果,它需要在執行此結果之前填充列表。

validate方法結束並返回INPUT結果之前,您正在validate方法中手動檢查驗證錯誤,然后重新填充列表。

此邏輯已由作為defaultStack成員的workflow攔截器實現。 您可以配置此攔截器以在發生驗證錯誤時調用方法。 在此方法中,您可以重新填充列表。

public String input() throws Exception {
  list = service.getList((int)(currentPage-1)*pageSize, pageSize);
  return INPUT;
}

現在,您應該通過在 crud 方法insert()delete()放置注釋來配置此方法以與workflow攔截器一起使用。

@InputConfig(methodName="input")

edit()load()方法中,如果操作返回調度程序結果(可能與INPUT結果相同的位置load()您可以手動調用input()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM