1. 程式人生 > >Struts2 框架的簡單實現——輕鬆理解Struts原理

Struts2 框架的簡單實現——輕鬆理解Struts原理

        Struts2因該算是目前JavaWeb中MVC框架中最火的一個了,我第一次接觸框架是在大學時期,那時候第一次學的還是Struts1框架,當時想的是:既然有1和2那就從低版本的開始學吧!當時自己想當然的將Struts2當成了Struts1的升級版本。可直到後來才發現自己大錯特錯,Struts2和Struts1雖然只有一字之差,但從實現原理到程式設計風格都是天壤之別。以至於我在很長一段時間都不能適應Struts2的編碼風格。關於Struts2和Struts1的區別我就不再多說,本文的重點是用相對簡單的程式碼模擬Struts2的底層實現。

    首先,Struts2的Controler這個角色是由Filter完成的。Filter通過攔截瀏覽器的請求,通過不同的請求選擇執行不同Action的excute()方法,最終決定該如何跳轉。

    先看一下如果我們平時不用Struts2框架時,用Filter如何實現以上功能。

    我們想寫一個JSP頁面,頁面上有兩個超連結

<a href = "/primer/userAction.action">userAction</a>
<a href = "/primer/helloWorldAction.action">helloWorldAction</a></span>

當我們點選頁面上的超練接時,瀏覽器就會想伺服器傳送請求,Filter就會攔截這個請求

我們的Filter就會這樣寫:

public class Struts2Filter implements Filter {

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		
		//強轉
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		
		String path = req.getServletPath();
                if(path.equals("/primer/userAction.action")){
                    Action a = new UserAction();
                    String result = a.excute();
                  req.getRequestDispatcher("/success.jsp").forward(req, res);  
                    }else if(path.equals("/primer/helloWorldAction.action")){
                         Action a = new HelloWorldAction();
                         String result = a.excute();
                         req.getRequestDispatcher("/success.jsp").forward(req, res);   
                        }
		
		

  }
}

以上程式碼乍一看並沒有什麼問題,但是我們假設這樣一種情況,如果瀏覽器頁面上有10個超練接,那不是要判斷十次,這顯然是不合理的,所以我們希望每次都能動態根據獲得的請求判斷該使用哪個Action。所以這就需要用到反射原理構建物件。那應該如何實現呢?首先我們新建一個HashMap,以連結地址為Key,以Action的全名為Value.

於是程式碼可以這樣修改。

public class Struts2Filter implements Filter {

	Map<String, String> map = new HashMap<String, String>();
	
	public void init(FilterConfig config) throws ServletException {
		map.put("/primer/userAction.action", "cn.itcast.action.UserAction");
		map.put("/primer/helloWorldAction.action", "cn.itcast.action.HelloWorldAction");</span>

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		
		//強轉
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		
		String path = req.getServletPath();
		
		System.out.println("path = "+path);
		
		if(path.equals("/test.jsp")){
			chain.doFilter(req, res);//如果.jsp則放行
		}else{
			try {
				Action action;
				
				//利用反射,通過newInstance()得到例項化
				action = (Action)Class.forName(map.get(path)).newInstance();
				
				action.execute();
				
				req.getRequestDispatcher("/success.jsp").forward(req, res);
				
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
	}

	public void destroy() {
		// TODO Auto-generated method stub

	}

}
    這樣看起來似乎好了很多,但仍然有問題,如果我們增加頁面上的超練接,就需要不斷往Map中增加元素,每次修改都需要重新載入Struts2Filter,這顯然比較浪費資源。為了解決這個問題我們可以建立一個XML檔案,然後把Action配置進去,之後我們只需要解析XML檔案,就能將元素放入Map中了,這個XML檔案就是Struts2中的Struts.xml檔案。

配置檔案如下:

<package name="packsge" namespace="/primer/" extends="struts-default">
        
        <action name="</span><span style="font-family:SimSun;font-size:14px;">userAction</span><span style="font-size:18px;">" class="cn.itcast.action.UserAction" method="excute">
            <result name="success">/success.jsp</result>
        </action>
     
        <action name="helloWorldAction" class="cn.itcast.action.HelloWorldAction" method="excute">
            <result name="success">/success.jsp</result>
        </action>
</package>

   然後,我們把Strust2Filter中紅色的硬性注入,改成解析XML檔案賦值就可以啦,這樣一個簡單的Struts2框架就搭建好了,在使用Struts2是,核心的Filter不需要我們修改,我們只需要配置struts2.xml檔案,和編寫Action類就OK啦,是不是很簡單!!!!當然,Struts2肯定不止這些東西,在struts-default.xml中還有無數的攔截器等著我們。這裡只是簡單的實現Struts2的一些基本功能。

  以上只是本人對於Struts2的一些粗淺理解,如有錯誤請各大高手批評指正!!!!!!