Struts2 框架的簡單實現——輕鬆理解Struts原理
阿新 • • 發佈:2019-02-14
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.
於是程式碼可以這樣修改。
這樣看起來似乎好了很多,但仍然有問題,如果我們增加頁面上的超練接,就需要不斷往Map中增加元素,每次修改都需要重新載入Struts2Filter,這顯然比較浪費資源。為了解決這個問題我們可以建立一個XML檔案,然後把Action配置進去,之後我們只需要解析XML檔案,就能將元素放入Map中了,這個XML檔案就是Struts2中的Struts.xml檔案。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 } }
配置檔案如下:
<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的一些粗淺理解,如有錯誤請各大高手批評指正!!!!!!