本文實例為大家分享了struts2自定義MVC框架的方法,供大家參考,具體內容如下
自定義MVC: (首先了解Model1和Model2的概念)
Model1與Model2:
Model1:就是一種純jsp開發技術,將業務邏輯代碼和視圖渲染代碼雜糅在一起。
Model2:Model2是在Model1的基礎上,將業務邏輯的代碼分離開來,單獨形成一個Servlet,Model2也是基於MVC開發。
總結MVC特點如下:
(1)數據的獲取和顯示分離
(2)控制器將不同的模型和視圖組合在一起
(3)應用分為三部分,三部分之間松耦合併協同工作,從而提高應用的可擴展性和可維護性
(4)各層負責不同的功能,各司其職,每一層的組件具有相同的特徵,便於通過工程化和工具化產生程序代碼
MVC思想及其優勢(很強勢)
MVC是一種架構模式,目的是將模型(業務邏輯)、視圖(表示層)分離,使模型和視圖可以獨立修改互不影響。大多數軟件在設計架構時都採用此模式。使用MVC模式有很多處,當一個通過瀏覽器瀏覽的系統想要開發手機版本時,只需要重新開發視圖,模型部分的業務邏輯可以重用。許多軟件需要同時推出B/S和C/S版本,採用MVC模式,模型部分可以重用,只需要開發不同的視圖即可。 MVC思想將一個應用分成三個基本部分M(Model,模型)V(View,視圖)C(Controller,控制器)。其中M表示處理業務邏輯的部分,V表示顯示數據和獲取用戶輸入的部分,C類似中介,保證M和V不會直接交互。
基本步驟如下:
1.創建XML文檔Framework.xml
2.定義Action接口
3.定義一個actionMapping類,視為action節點
4.定義ActionMappingManage類來管理ActionMapping類(actions節點)
5.定義ActionManager類使用反射機制根據字符串類型的類名獲取到具體的類(web.xml標籤的書寫)
6.編寫servlet進行運行時機的控制
7.定義LoginAction類進行測試
1.創建XML文檔Framework.xml
<!--?xml version="1.0" encoding="UTF-8"?--><!-- 定義約束文件-->(標註)<!-- ELEMENT 表示元素--><!-- ATTLIST 表示屬性--><!-- CDATA 表示字符串類型--><!-- REQUIRED 表示此屬性必須的寫--><!-- *代表多個--><!-- IMPLIED 表示此屬性可寫--><!-- redirect 重定向或轉發--> <!--ELEMENT actions (action)--> <!--ELEMENT action (result*)-->(*表示可以多個) <!--ATTLIST action name CDATA #REQUIRED class CDATA #REQUIRED --> <!--ATTLIST RESULT name CDATA #IMPLIED redirect (true|false) "false" -->]><framework> <!-- 進行測試--><actions> <action name="loginAction"> <result name="success">success.jsp</result> <result name="login">index.jsp</result> </action></actions></framework>
注意:空格和<>的書寫規範。
節點的層次。
2.定義Action接口
注意:excute參數的書寫,請求和響應。
3.定義一個actionMapping類,視為action節點(進行action節點的標籤的書寫)
進行封裝字段和results集合的添加數據。
注意:添加數據的書寫。 (Map集合)
4.定義ActionMappingManage類來管理ActionMapping類(actions節點)
/* * action節點不止一個* 用來來管理ActionMapping類*/public class ActionMappingManager { //actionMapping類的集合private Map<String,ActionMapping> maps=new HashMap<String,ActionMapping>(); public ActionMapping getActionMapping(String name) { return maps.get(name); } //解析在src項目下的所有配置文件//實例化完畢後進行解析public ActionMappingManager(String[] file){ for (String filename : file) { Init(filename); } } //init初始化方法//解析xml文檔public void Init(String path){ try { InputStream is=this.getClass().getResourceAsStream("/"+path); //解析xml Document doc=new SAXReader().read(is); //獲取根節點Element root = doc.getRootElement(); //獲取actions節點Element actions=(Element)root.elementIterator("actions").next(); //使用for循環來遍歷actions節點下的所有action節點for(Iterator<Element> action=actions.elementIterator("action");action.hasNext();) { //獲取到<action>節點Element actionnext = action.next(); //分別獲取到action節點中的name屬性和class屬性String name = actionnext.attributeValue("name"); String classname = actionnext.attributeValue("class"); //將以上兩個屬性保存到ActionMapping類中ActionMapping mapp=new ActionMapping(); mapp.setClassname(classname); mapp.setName(name); //由於一個action節點下有多個result節點遍歷action下所有的result節點for(Iterator<Element> result=actionnext.elementIterator("result");result.hasNext();) { //獲取到result節點Element resultnext = result.next(); //提取result節點的name屬性值和result節點中的值String resultname = resultnext.attributeValue("name"); String resultvalue=resultnext.getText(); //將其分別存入到actionMapping中的雙列集合中去,方便調用actionMapping類(actionMapping類中就有數據了!) mapp.addResult(resultname, resultvalue); System.out.println(mapp.getName()); } //得到所有action節點的集合maps.put(mapp.getName(), mapp); } } catch (Exception e) { // TODO: handle exception } } }概括:
通過dom4j解析Framework.xml配置文件。從而獲取根節點,以及actions節點,並通過for循環遍歷actions節點下的action節點拿到name和class的屬性值,由於一個action節點下有多個result節點及遍歷action下所有的result節點,分別存入到actionMapping中的雙列集合中,最後得到所有action節點的集合。
注意:Init方法的書寫,以及ActionMappingManager帶參數組的書寫。
5.定義ActionManager類使用反射機制根據字符串類型的類名獲取到具體的類
public class ActionManager { public static Action getActionClass(String classname) { Class clazz=null; Action action=null; //獲取當前線程的類加載器try { //如果線程中的有那麼一個類,直接根據類名獲取該類的類型clazz=Thread.currentThread().getContextClassLoader().loadClass(classname); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(clazz==null) { try { //如果該線程中沒有,那麼使用class.forname方法獲取clazz=Class.forName(classname); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(action==null) { try { //將獲取到的類型轉換為action,調用無參構造函數,某種程度上相當於new,不過new需要指定類型action=(Action)clazz.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return action; }}web.xml的節點配置:
6.編寫servlet進行運行時機的控制(servlet,初始化所有的類)
public class MyServlet extends HttpServlet { /** *你很菜*/ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }<br> /** *繼續努力*/ ActionMappingManager man=null; public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取ActionMapping對象ActionMapping actionMapping = man.getActionMapping(getPath(request)); //獲取action接口反射機制Action action = ActionManager.getActionManager(actionMapping.getClassname()); try { String message=action.execute(request, response); String results = actionMapping.getResults(message); response.sendRedirect(results); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * 獲取請求的路徑名*/ public String getPath(HttpServletRequest request){ //項目+請求地址String requestURI = request.getRequestURI(); //項目名稱String contextPath = request.getContextPath(); //具體請求String path = requestURI.substring(contextPath.length()); String filename = path.substring(1,path.lastIndexOf(".")); return filename; } /* *重寫init,程序運行加載所有類* */ @Override public void init(ServletConfig config) throws ServletException { //config對像是javax.servlet.ServletConfig的對象,功能是獲得初始化配置信息//config.getInitParameter是取得指定名稱的初始化參數內容String filename = config.getInitParameter("config"); String [] filenames=null; if(filename==null){ //如果為空, filenames=new String[]{"Framework.xml"}; }else{ //若果有其他的配置參數信息,那麼以,分隔存入數組中filenames=filename.split(","); } //使用init方法進行初始化man=new ActionMappingManager(filenames); }}注意:代碼的層次及註釋。
7.定義LoginAction類進行測試
public class LoginAction implements Action{ @Override public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception { String name = request.getParameter("name"); String pwd = request.getParameter("pwd"); if(name.equals("1")&&pwd.equals("1")){ return SUCCESS; }else{ return LOGIN; } }}jsp代碼:
實現效果:
再長的路,一步步也能走完,再短的路,不邁開雙腳也無法到達。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。