2025-05-23

 

 

在上篇文章中,我們已經從較高層解釋瞭整個框架的結構,請求流程的基礎,配置方式和Struts2和Struts1的不同之處。瞭解這些後從Struts 應用 遷移到Struts 2 不再是難事。

    在這篇文章中,我們將會更詳細地講述如何由Struts 的action轉為Struts 2的action。

 

一個應用的例子

這個例子選擇瞭大傢都熟悉的- weblog. 簡單地介紹下這例子的功能需求:

•     增加一個新的日志

•     察看一個日志

•     修改一個日志

•     刪除一個日志

•     列出所有日至 

     增刪修改(CRUD),是項目中最為普遍的應用。

     業務邏輯類在Struts 和Struts2 應用都是可共用的。如:

public class BlogService …{

private static List<Blog> blogs = new ArrayList<Blog&gt;();

public List<Blog> list() …{ … }

public Blog create(Blog blog) …{ … }

public void update(Blog blog) …{ … }

public void delete(int id) …{ … }

public Blog findById(int id) …{ … }

}

 

    BlogService 隻是個簡單的業務邏輯類,並不是接口,Struts 和Struts2 的action皆可調用其實例。雖然這樣設計在實際項目中會帶來不必要的耦合,但我們的例子隻是集中在討論web層上,所以無關重要。

 

QUOTE:

 

    工具箱: 在第一篇文章中,我們談論瞭在Struts2 actions中的依賴註入的接口註入方式。這個是servlet 相關類(HttpServletRequest, HttpServletResponse, PrincipalProxy, 等.)的主要註入方式,但這並不是唯一的方式。

Struts2 可以使用Spring框架作為默認的容器時,依賴註入的setter方法就可用瞭。通過在action中加入setter方法(如下演示),Struts2 框架將能從Spring框架中獲得正確的信息,並通過setter加載在action中。

public void setBlogService(BlogService service) …{

     this.blogService = service;

}

    和接口註入方式類似,我們需要一個攔截器來幫助我們完成任務,這就是ActionAutowiringInterceptor 攔截器。這樣我們的業務邏輯類就通過Spring框架管理自動在action被調用之前註入到Struts2得action中。有多種的配置參數(如by name, by type 或automatically)可供選擇,可以讓對象和setter匹配的註入的方式根據你的需要而定。

Struts 應用中的代碼

 

     我們首先從Struts講起。在Struts中,最普遍的做法是,對於每個需求用例(如save,update,remove,list)來說都會有對應的action類,同時也會有相應的action form類。在我們的應用中的這個方式或許不是最佳的實現方式(其他的解決方案包括使用dynamic form或者使用request來分發action),但我們例子中的做法是所有Struts開發者最熟悉的一種形式。瞭解瞭這種簡單的實現方法,你有能力在遷移到Struts2時,使用更為優秀的方法。

在第一篇文章中我們談過Struts 和Struts2 中action的區別。現在我們從UML中再次看看他們的差別。一般來說form在Struts action中的表現形式是: 下圖image1.jpg

這action form將會在多個action中使用,讓我們來看看它:

public class BlogForm extends ActionForm …{

private String id;

private String title;

private String entry;

private String created;

// public setters and getters for all properties

}

 

如UML中展示的那樣,其中一個限制就是必須繼承ActionForm類,另外一個限制就是form中所有屬性都必須是String類型,所以所有的getter和setter都必須隻能接受String參數和返回String結果。

 

然後我們來看看action。我們這個例子中的action有view, create 和update action。

The View Action:

The Create Action:

public class ViewBlogAction extends Action …{

public ActionForward execute(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws Exception …{

BlogService service = new BlogService();

String id = request.getParameter("id");

request.setAttribute("blog",service.findById(Integer.parseInt(id)));

return (mapping.findForward("success"));

}

}

public class SaveBlogEntryAction extends Action …{

public ActionForward execute(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws Exception …{

BlogService service = new BlogService();

BlogForm blogForm = (BlogForm) form;

Blog blog = new Blog();

BeanUtils.copyProperties( blog, blogForm );

service.create( blog );

return (mapping.findForward("success"));

}

}

public class UpdateBlogEntryAction extends Action …{

public ActionForward execute(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws Exception …{

BlogService service = new BlogService();

BlogForm blogForm = (BlogForm) form;

Blog blog = service.findById( Integer.parseInt(blogForm.getId()));

BeanUtils.copyProperties( blog, blogForm );

service.update( blog );

request.setAttribute("blog",blog);

return (mapping.findForward("success"));

}

}

 

這三個action都跟隨著同一個模式:

    產生一個新的業務邏輯對象實例- 如前面所提到的,我們使用最直接的方式在action中使用業務邏輯對象,這表示在每個action中都會產生新的業務邏輯對象實例。

 

    從請求中獲得數據- 這是兩種形式之一。在view action中,"id"是從HttpServletRequest 對象中直接獲取的。而在create 和update action 中,則從ActionForm 中取值。ActionForm 與HttpServletRequest 的調用方式其實很相似,唯一不同的ActionForm 是bean的從field中取值。

調用業務邏輯- 現在開始生成調用業務邏輯所需的參數並調用邏輯。如果參數(在view action中)是一個簡單對象類型,則轉換值時會自動轉為正確的類型(如從String轉到Integer)。如果參數是復雜的對象類型,,則ActionForm 需要通過BeanUtil 來幫忙轉成相應的對象。

 

    設定返回的數據- 如果需要把數據返回顯示給用戶,那則要把這個數據設在HttpServletRequest 的attribute 中返回。返回一個ActionForward – 所有Struts action的最後都需要找到並返回其相應的ActionForward 對象.

 

     最後的兩個action,remove和list action, 隻有很少的差別。remove action如下所示,沒有用BlogForm類. 通過從request的attribute中獲取"id"(和view action相似),就能調用業務邏輯完成其需要的工作。在下面我們介紹配置時,你可以看到它並沒有返回任何數據,因為它的"success"返回結果其實是執行remove後再執行瞭list action來返回信息的。

public class RemoveBlogEntryAction extends Action …{

public ActionForward execute(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws Exception …{

BlogService service = new BlogService();

String id = request.getParameter("id");

service.delete(Integer.parseInt(id));

return (mapping.findForward("success"));

}

}

 

 

list action並不需要任何的用戶輸入,它隻是簡單地調用瞭業務邏輯的無參方法,同時返回所有的Blog對象。

public class ListBlogsAction extends Action …{

public ActionForward execute(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws Exception …{

BlogService service = new BlogService();

request.setAttribute("bloglist",service.list());

return (mapping.findForward("success"));

}

}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *