了解MVC MVC是Model,View,Controller的縮寫,MVC是Application開發的設計模式,也就是大家所知道的Model2.在MVC的設計模式中,要求在Application開發中你把商業邏輯,界面顯示,數據分離。也就是分別在Model,View,Controller實現:數據,控制(商業邏輯),顯示(頁面顯示). 在以前或者說傳統的Web Application開發方式當中,如Asp,Php,Jsp(Model 1)開發當中,我們在Asp(Php,Jsp)中實現一切,如:從數據庫中取到我們需要的數據,并根據數據之間的關聯和實際的需要按照某種方式把他顯示在頁面中以及從頁面提交的表單中提取數據,根據商業邏輯從數據庫查詢相關數據,或者把數據寫入數據庫。也就是說我們在Asp(Php,Jsp)實現一切包括:界面顯示,商業邏輯,數據存取。這樣帶來的后果就是你所寫的Asp(Php,Jsp)沒有層次,并且Html和Script(JavaScript、JScript,Asp、Php、Jsp源代碼)相互嵌套.可維護性差,最要命的是在Web Application通常顯示一塊是由美工完成的,很多時候也是你先寫好Asp、Php、Jsp然后美工進行美化,很有可能你發現經過美工處理完以后你的代碼已經面目全非了。你不得不把你的代碼重新組織。 在MVC模式中這個問題的解決辦法是:View中負責顯示,View一般從Controller得到已經處理\過的數據,然后顯示在頁面當中,應該說這樣在Html中嵌套很少的Script.基本上美工的修改不大會廢掉你的勞動成果。 在使用Java開發Web Application有幾種符合MVC設計模式的開發方式讓你選擇。 1:Jsp+Servlet+JavaBean(EJB) 2:Jsp+JavaBean(Controller)+JavaBean(EJB)(Model) 3:TDK(Turbine,Velocity...) 4:Xsp 5:Jsp+Struts+JavaBean(EJB) 我個人認為后面兩種比較好,其他幾種都有可取的地方特別是使用TDK因為有一個比較好的工具可以自動生成很多代碼,至于它的缺點在后面幾種開發方式的比較當中我會介紹。 Struts1.1的新功能 Struts1.1與1.0相比加了一些很不錯的功能。最主要是表單驗證上功能增強。在Struts1.1數據的驗證不象以前在Action中在validator具體實現,而是在validation.xml通過配置實現這樣做的好處就是重用性加強了很多。
Struts1.1實現的主要組成 主要包括:Action,ActionForm,ActionMapping,ActionForward,開發當中最主要寫的是Action,ActionForm根據需要可以寫或不寫。下面我就一一具體介紹。 Action An Action is an adapter between the contents of an incoming HTTP request and the corresponding business logic that should be executed to process this request. 上面是Struts開發小組對Action的描述,說Action實際上Request和Business Logic中間的適配器.通俗的說就是從表單中取到數據并穿給商業邏輯操作進行一系列的操作,然后返回相應的操作信息。 ActionForm An ActionForm is a JavaBean optionally associated with one or more ActionMappings. Such a bean will have had its properties initialized from the corresponding request parameters before the corresonding action's execute() method is called. ActionForm實際上就是把從Request取到的數據封裝并進行校驗,然后把合法的數據給Action進行處理。實際上ActionForm除了進行數據校驗之外另外更重要的是在表單回寫的時候作用很大。反而在1.1以后數據校驗的大部分工作在validation.xml去實現。 ActionMapping,ActionForward ActionMapping主要是用與配置和描述相關屬性使用的。先看下在struts-config.xml 中的配置文件一段配置描述: <action-mappings> <!-- Registration Action --> <action path="/usereg" type="com.bingo.finance.action.UseregAction" name="useregForm" scope="request" validate="true" input="/usereg.jsp"> <forward name="success" path="/msg.jsp"/> </action> </action-mappings> ActionMapping就是用來描述一個Action的URL、具體實現的文件、相對應的ActionForm 數據屬性(request or session)、是否需要進行數據校驗和回寫、以及處理完成后可能跳轉的URL. 而ActionForward你就可以理解為Action 操作完成后的跳轉URL,Action在處理完相關操作后,返回的是一個ActionForward也就是告訴Struts我做完這個操作下一步到哪兒去。
構建Struts1.1運行環境 我的配置是居于Tomcat4.0以上版本討論,其他的AppServer大致相同。 1:得到Struts1.1 http://jakarta.apache.org/builds/jakarta-struts/release/v1.1-b1/jakarta-struts-1.1-b1.zip 2:設置 把Struts.jar Copy到$Tomcat_home/common/lib 或你使用Struts的Appaction下的WEB-INF/lib下 在你使用Struts的Appaction下web.xml中增加下列配置 <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib>
<taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib>
<!-- Nested Tag Library Descriptor --> <taglib> <taglib-uri>/WEB-INF/struts-nested.tld</taglib-uri> <taglib-location>/WEB-INF/struts-nested.tld</taglib-location> </taglib>
<!-- Template Tag Library Descriptor --> <taglib> <taglib-uri>/WEB-INF/struts-template.tld</taglib-uri> <taglib-location>/WEB-INF/struts-template.tld</taglib-location> </taglib> Struts1.1中提供了很詳細的例子,你可以仔細看看. 接下來你該根據需要配置struts-config.xml,以下是一個簡單的例子 <?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config> <!-- ========== Form Bean Definitions =================================== --> <form-beans> <!-- Registration form bean --> <form-bean name="useregForm" type="com.bingo.finance.action.UserForm"/> </form-beans> <!-- ========== Global Forward Definitions ============================== --> <global-forwards> <forward name="error" path="/error.jsp"/> </global-forwards> <!-- ========== Action Mapping Definitions ============================== --> <action-mappings> <!-- Registration Action --> <action path="/usereg" type="com.bingo.finance.action.UseregAction" name="useregForm" scope="request" validate="true" input="/usereg.jsp"> <forward name="success" path="/msg.jsp"/> </action> </action-mappings> <!-- ========== Message Resources Definitions =========================== --> <message-resources parameter="com.bingo.finance.common.DisplayMsg"/> <!-- ========== Plug Ins Configuration ================================== --> <!-- Add multiple validator resource files by setting the pathname property --> <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathname" value="/WEB-INF/validator-rules.xml"/> <set-property property="pathname" value="/WEB-INF/validation.xml"/> </plug-in> </struts-config> 上面的英文我相信你能夠看懂。我就不做解釋了。你需要繼續配置validation.xml了,看如下 簡單的例子. <form-validation> <formset> <form name="useregForm"> <field property="username" depends="required,mask,minlength,maxlength"> <arg0 key="common_username"/> <arg1 name="minlength" key="${var:minlength}" resource="false"/> <arg1 name="maxlength" key="${var:maxlength}" resource="false"/> <var> <var-name>mask</var-name> <var-value>^\w+$</var-value> </var> <var> <var-name>minlength</var-name> <var-value>5</var-value> </var> <var> <var-name>maxlength</var-name> <var-value>20</var-value> </var> </field> <field property="password" depends="required,mask,minlength,maxlength"> <arg0 key="common_password"/> <arg1 name="minlength" key="${var:minlength}" resource="false"/> <arg1 name="maxlength" key="${var:maxlength}" resource="false"/> <var> <var-name>mask</var-name> <var-value>^\w+$</var-value> </var> <var> <var-name>minlength</var-name> <var-value>5</var-value> </var> <var> <var-name>maxlength</var-name> <var-value>20</var-value> </var> </field> <field property="nickname" depends="required,mask,minlength,maxlength"> <arg0 key="common_nickname"/> <arg1 name="minlength" key="${var:minlength}" resource="false"/> <arg1 name="maxlength" key="${var:maxlength}" resource="false"/> <var> <var-name>mask</var-name> <var-value>^\w+$</var-value> </var> <var> <var-name>minlength</var-name> <var-value>5</var-value> </var> <var> <var-name>maxlength</var-name> <var-value>20</var-value> </var> </field> <field property="superpass" depends="required,mask,minlength,maxlength"> <arg0 key="common_superpass"/> <arg1 name="minlength" key="${var:minlength}" resource="false"/> <arg1 name="maxlength" key="${var:maxlength}" resource="false"/> <var> <var-name>mask</var-name> <var-value>^\w+$</var-value> </var> <var> <var-name>minlength</var-name> <var-value>10</var-value> </var> <var> <var-name>maxlength</var-name> <var-value>20</var-value> </var> </field> </form> </formset> </form-validation> 上面validation.xml就是告訴Struts我的useregForm取到的數據應該做下面的驗證 username是必須不能為空的并且最小長度為5,最大長度是20. ................ password,nickname,superpass基本一樣我就不做更多說明.至次配置基本結束,我們要開始寫第一個Struts 了。 開發Struts1.1 usereg.jsp 為了考慮頁面的靈活性,在頁面中顯示的所有元素我都放在properties文件中并由com.bingo.finance.common.HtmlMsg這個文件取到. =================================================================== <%@ page contentType="text/html;charset=GBK" %> <%@ page import="java.io.*"%> <%@ page import="com.bingo.finance.common.HtmlMsg"%> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<html> <head> <title><%=HtmlMsg.TITLE_REGISET%></title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head> <body bgcolor="#FFFFFF" text="#000000"> <form name="usereg" method="post" action="usereg.esp"> <!--在Struts中默認的后綴是.do你可以根據需要自己修改--> <table width="100%" border="0" cellspacing="1" cellpadding="1"> <tr align="center"> <td colspan="2"><%=HtmlMsg.TITLE_REGISET%></td> </tr> <tr> <td width="49%" align="right"><%=HtmlMsg.COMMON_USERNAME%>:</td> <td width="51%"> <!--為了實現回寫在Struts中建議你使用Tag使用如下寫法代替一般的寫法 <html:text property="username" size="20" maxlength="30" styleClass="css" styleId="userId"/> 上面的代碼你看不懂你需要進一步了解Tag. --> <input type="text" name="username" size="20" maxlength="20"> </td> </tr> <tr> <td width="49%" align="right"><%=HtmlMsg.COMMON_PASSWORD%>:</td> <td width="51%"> <input type="password" name="password" size="20" maxlength="20"> </td> </tr> <tr> <td width="49%" align="right"><%=HtmlMsg.COMMON_NICKNAME%>:</td> <td width="51%"> <input type="text" name="nickname" size="20" maxlength="20"> </td> </tr> <tr> <td width="49%" align="right"><%=HtmlMsg.COMMON_SUPERPASS%>:</td> <td width="51%"> <input type="password" name="superpass" size="20" maxlength="20"> </td> </tr> <tr> <td width="49%" align="right"> <input type="submit" name="Submit" value="<%=HtmlMsg.ACTION_REGISET%>"> </td> <td width="51%"> <input type="reset" name="Submit2" value="<%=HtmlMsg.COMMON_RESET%>"> </td> </tr> </form> </body> </html> UseregActiom.java =========================================================== package com.bingo.finance.action;
//java import import java.io.IOException; import java.util.Locale; //servlet import import javax.servlet.ServletException; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //struts import import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.util.MessageResources; //finance import import com.bingo.finance.action.UserForm; import com.bingo.finance.manager.UserManager; import com.bingo.finance.entity.User; public class UseregAction extends Action { //在Struts1.1以前使用perform //struts1.1使用execute替代perform public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try{ UserForm userForm=(UserForm)form; UserManager userManager=new UserManager(); User user=userManager.formToEntity(userForm); userManager.add(user); //Insert into DataBase a Userinfo }catch(Exception ex){ return mapping.findForward("error"); } return mapping.findForward("success"); //ForWard is "/msg.jsp" } } UserForm.java ========================================================================= package com.bingo.finance.action; import java.util.*; import java.io.Serializable; //servlet import import javax.servlet.ServletException; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //struts import import org.apache.struts.action.ActionMapping; import org.apache.struts.validator.ValidatorForm; public class UserForm extends ValidatorForm implements Serializable{ //在Struts1.1以前通常Form繼承ActionForm //實際上ValidatorForm是繼承ActionForm //為什么要加一層ValidatorForm是為了校驗而做的 private String id; private String username; private String password; private String nickname; private String superpass; public UserForm(){ } /****/ public String getId(){ return this.id; } /****/ public void setId(String _id){ this.id=_id; } /****/ public String getUsername(){ return this.username; } /****/ public void setUsername(String _username){ this.username=_username; } /****/ public String getPassword(){ return this.password; } /****/ public void setPassword(String _password){ this.password=_password; } /****/ public String getNickname(){ return this.nickname; } /****/ public void setNickname(String _nickname){ this.nickname=_nickname; } /****/ public String getSuperpass(){ return this.superpass; } /****/ public void setSuperpass(String _superpass){ this.superpass=_superpass; } /**show this class info**/ public String toString(){ StringBuffer info=new StringBuffer(); info.append("....id is:"+id); info.append("....username is:"+username); info.append("....password is:"+password); info.append("....nickname is:"+nickname); info.append("....superpass is:"+superpass); return info.toString(); } public void reset(ActionMapping mapping, HttpServletRequest request) { id=null; username=null; password=null; nickname=null; superpass=null; } } UserManager.java ,User.java文件我就不提供了,這一部分在實際的開發當中根據需要自己去處理,也就是為了把數據插入數據庫。 現在一個簡單的注冊用戶你就開發完成了。很簡單吧。呵呵,繼續努力...但其中還有很多 細節你需要進一步了解,我只把你領到門了,你必須自己去研究一些東西,比如說,我希望我的用戶多一個Email字段和一個年齡字段我應該如何做,而且我希望validation.xml的驗證有Email合法驗證,年齡必須大于0而且一定是整數。那我應該如何做?我只能告訴你加兩個字段你需要修改Form 增加字段,同時相應文件也要修改。在struts中Email的驗證非常簡單。好好看例子吧,好好研究validator-rules.xml,這個我認為struts1.1最好的功能增加(Struts1.0沒有這個文件)。Struts中提供了一個非常靈活而且重用極高的驗證機制。
Struts和其他開發方式的比較 使用Struts開發至少帶來如下好處: 1:層次結構非常清晰,也使得分工很明確。 2:重用度很高,連數據驗證都可以重用,還有一個更好的重用就是Form,Action是可以很好的重用的。 3:可維護性好。這是居于第一點的。 ................. 下面我說一個Struts的不足之處,如果你使用或者了解TDK你就會覺得,TDK中可以自動生成很多java源代碼的確可以節省不少工作量,Struts中也可以做的很好。我自己開發了一個工具,功能還不夠強大。在我的計劃當中,我希望Form,JavaBean(封裝數據相當于EJB中的Entity Bean),甚至包括操作數據庫的Method都自動生成,還有validation.xml也可以動態的生成。然而因為下一個原因:Struts到目前為止還不是一個比較成熟的項目。他的改動實在是太大了。1.0和0.5就有很大的改動。所以我的計劃有變。我希望在1.1完全推出來再做開發(1.1現在是Beta版)。同時我也給Craig R. McClanahan(Struts開發的Team leader)寫過信聽取他的建議.
|