<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    心的方向

    新的征途......
    posts - 75,comments - 19,trackbacks - 0

    Struts+Spring+Hibernate實現上傳下載(四)

    轉自:http://lihaiyan.javaeye.com/blog/127797

    Web層實現

      1、Web層的構件和交互流程

      Web層包括主要3個功能:

      ·上傳文件。

      ·列出所有已經上傳的文件列表,以供點擊下載。

      ·下載文件。

      Web層實現構件包括與2個JSP頁面,1個ActionForm及一個Action:

      ·file-upload.jsp:上傳文件的頁面。

      ·file-list.jsp:已經上傳文件的列表頁面。

      ·FileActionForm:file-upload.jsp頁面表單對應的ActionForm。

      ·FileAction:繼承org.apache.struts.actions.DispatchAction的Action,這樣這個Action就可以通過一個URL參數區分中響應不同的請求。

      Web層的這些構件的交互流程如圖 6所示:

    420){this.resized=true;this.style.width=420;}" border=0 resized="true">
    圖 6 Web層Struts流程圖


      其中,在執行文件上傳的請求時,FileAction在執行文件上傳后,forward到loadAllFile出口中,loadAllFile加載數據庫中所有已經上傳的記錄,然后forward到名為fileListPage的出口中,調用file-list.jsp頁面顯示已經上傳的記錄。

      2、FileAction功能

      Struts 1.0的Action有一個弱項:一個Action只能處理一種請求,Struts 1.1中引入了一個DispatchAction,允許通過URL參數指定調用Action中的某個方法,如http://yourwebsite/fileAction.do?method=upload即調用FileAction中的upload方法。通過這種方式,我們就可以將一些相關的請求集中到一個Action當中編寫,而沒有必要為某個請求操作編寫一個Action類。但是參數名是要在struts-config.xml中配置的:

    1. <struts-config>
    2. <form-beans>
    3. <form-bean name="fileActionForm" type="sshfile.web.FileActionForm" />
    4. </form-beans>
    5. <action-mappings>
    6. <action name="fileActionForm" parameter="method" path="/fileAction"
    7. type="sshfile.web.FileAction">
    8. <forward name="fileListPage" path="/file-list.jsp" />
    9. <forward name="loadAllFile" path="/fileAction.do?method=listAllFile" />
    10. </action>
    11. </action-mappings>
    12. </struts-config>


      第6行的parameter="method"指定了承載方法名的參數,第9行中,我們還配置了一個調用FileAction不同方法的Action出口。

      FileAction共有3個請求響應的方法,它們分別是:

      ·upload(…):處理上傳文件的請求。

      ·listAllFile(…):處理加載數據庫表中所有記錄的請求。

      ·download(…):處理下載文件的請求。

      下面我們分別對這3個請求處理方法進行講解。

      2.1 上傳文件

      上傳文件的請求處理方法非常簡單,簡之言之,就是從Spring容器中獲取業務層處理類FileService,調用其save(FileActionForm form)方法上傳文件,如下所示:

    1. public class FileAction
    2. extends DispatchAction
    3. {
    4. //將上傳文件保存到數據庫中
    5. public ActionForward upload(ActionMapping mapping, ActionForm form,
    6. HttpServletRequest request,
    7. HttpServletResponse response)
    8. {
    9. FileActionForm fileForm = (FileActionForm) form;
    10. FileService fileService = getFileService();
    11. fileService.save(fileForm);
    12. return mapping.findForward("loadAllFile");
    13. }
    14. //從Spring容器中獲取FileService對象
    15. private FileService getFileService()
    16. {
    17. ApplicationContext appContext = WebApplicationContextUtils.
    18. getWebApplicationContext(this.getServlet().getServletContext());
    19. return (FileService) appContext.getBean("fileService");
    20. }
    21. …
    22. }


      由于FileAction其它兩個請求處理方法也需要從Spring容器中獲取FileService實例,所以我們特別提供了一個getFileService()方法(第15~21行)。重構的一條原則就是:"發現代碼中有重復的表達式,將其提取為一個變量;發現類中有重復的代碼段,將其提取為一個方法;發現不同類中有相同的方法,將其提取為一個類"。在真實的系統中,往往擁有多個Action和多個Service類,這時一個比較好的設置思路是,提供一個獲取所有Service實現對象的工具類,這樣就可以將Spring 的Service配置信息屏蔽在一個類中,否則Service的配置名字散落在程序各處,維護性是很差的。

      2.2 列出所有已經上傳的文件

      listAllFile方法調用Servie層方法加載T_FILE表中所有記錄,并將其保存在Request域中,然后forward到列表頁面中:

    1. public class FileAction
    2. extends DispatchAction
    3. {
    4. …
    5. public ActionForward listAllFile(ActionMapping mapping, ActionForm form,
    6. HttpServletRequest request,
    7. HttpServletResponse response)
    8. throws ModuleException
    9. {
    10. FileService fileService = getFileService();
    11. List fileList = fileService.getAllFile();
    12. request.setAttribute("fileList",fileList);
    13. return mapping.findForward("fileListPage");
    14. }
    15. }


      file-list.jsp頁面使用Struts標簽展示出保存在Request域中的記錄:

    1. <%@page contentType="text/html; charset=GBK"%>
    2. <%@taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
    3. <%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
    4. <html>
    5. <head>
    6. <title>file-download</title>
    7. </head>
    8. <body bgcolor="#ffffff">
    9. <ol>
    10. <logic:iterate id="item" name="fileList" scope="request">
    11. <li>
    12. <a href='fileAction.do?method=download&fileId=
    13. <bean:write name="item"property="fileId"/>'>
    14. <bean:write name="item" property="fileName"/>
    15. </a>
    16. </li>
    17. </logic:iterate>
    18. </ol>
    19. </body>
    20. </html>


      展現頁面的每條記錄掛接著一個鏈接地址,形如:fileAction.do?method=download&fileId=xxx,method參數指定了這個請求由FileAction的download方法來響應,fileId指定了記錄的主鍵。

      由于在FileActionForm中,我們定義了fileId的屬性,所以在download響應方法中,我們將可以從FileActionForm中取得fileId的值。這里涉及到一個處理多個請求Action所對應的ActionForm的設計問題,由于原來的Action只能對應一個請求,那么原來的ActionForm非常簡單,它僅需要將這個請求的參數項作為其屬性就可以了,但現在一個Action對應多個請求,每個請求所對應的參數項是不一樣的,此時的ActionForm的屬性就必須是多請求參數項的并集了。所以,除了文件上傳請求所對應的fileContent和remark屬性外還包括文件下載的fileId屬性:

    420){this.resized=true;this.style.width=420;}" border=0>
    圖 7 FileActionForm


      當然這樣會造成屬性的冗余,比如在文件上傳的請求中,只會用到fileContent和remark屬性,而在文件下載的請求時,只會使用到fileId屬性。但這種冗余是會帶來好處的--它使得一個Action可以處理多個請求。

      2.3 下載文件

      在列表頁面中點擊一個文件下載,其請求由FileAction的download方法來響應,download方法調用業務層的FileService方法,獲取文件數據并寫出到response的響應流中。通過合理設置HTTP響應頭參數,將響應流在客戶端表現為一個下載文件對話框,其代碼如下所示:

      代碼 10 業務接口實現類之download

    1. public class FileAction
    2. extends DispatchAction
    3. {
    4. …
    5. public ActionForward download(ActionMapping mapping, ActionForm form,
    6. HttpServletRequest request,
    7. HttpServletResponse response)
    8. throws ModuleException
    9. {
    10. FileActionForm fileForm = (FileActionForm) form;
    11. FileService fileService = getFileService();
    12. String fileName = fileService.getFileName(fileForm.getFileId());
    13. try
    14. {
    15. response.setContentType("application/x-msdownload");
    16. response.setHeader("Content-Disposition",
    17. "attachment;" + " filename="+
    18. new String(fileName.getBytes(), "ISO-8859-1"));
    19. fileService.write(response.getOutputStream(), fileForm.getFileId());
    20. }
    21. catch (Exception e)
    22. {
    23. throw new ModuleException(e.getMessage());
    24. }
    25. return null;
    26. }
    27. }


      第15~18行,設置HTTP響應頭,將響應類型設置為application/x-msdownload MIME類型,則響應流在IE中將彈出一個文件下載的對話框,如圖 4所示。IE所支持的MIME類型多達26種,您可以通過這個網址查看其他的MIME類型:

    http://msdn.microsoft.com/workshop/networking/moniker/overview/appendix_a.asp

      如果下載文件的文件名含有中文字符,如果不對其進行硬編碼,如第18行所示,客戶文件下載對話框中出現的文件名將會發生亂碼。
    第19行代碼獲得response的輸出流,作為FileServie write(OutputStream os,String fileId)的入參,這樣文件的內容將寫到response的輸出流中。

      3、web.xml文件的配置

      Spring容器在何時啟動呢?我可以在Web容器初始化來執行啟動Spring容器的操作,Spring提供了兩種方式啟動的方法:

      ·通過org.springframework.web.context .ContextLoaderListener容器監聽器,在Web容器初始化時觸發初始化Spring容器,在web.xml中通過<listener></listener>對其進行配置。

      ·通過Servlet org.springframework.web.context.ContextLoaderServlet,將其配置為自動啟動的Servlet,在Web容器初始化時,通過這個Servlet啟動Spring容器。

      在初始化Spring容器之前,必須先初始化log4J的引擎,Spring也提供了容器監聽器和自動啟動Servlet兩種方式對log4J引擎進行初始化:

      ·org.springframework.web.util .Log4jConfigListener

      ·org.springframework.web.util.Log4jConfigServlet

      下面我們來說明如何配置web.xml啟動Spring容器:

      代碼 11 web.xml中對應Spring的配置內容

    1. <web-app>
    2. <context-param>
    3. <param-name>contextConfigLocation</param-name>
    4. <param-value>/WEB-INF/applicationContext.xml</param-value>
    5. </context-param>
    6. <context-param>
    7. <param-name>log4jConfigLocation</param-name>
    8. <param-value>/WEB-INF/log4j.properties</param-value>
    9. </context-param>
    10. <servlet>
    11. <servlet-name>log4jInitServlet</servlet-name>
    12. <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class>
    13. <load-on-startup>1</load-on-startup>
    14. </servlet>
    15. <servlet>
    16. <servlet-name>springInitServlet</servlet-name>
    17. <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    18. <load-on-startup>2</load-on-startup>
    19. </servlet>
    20. …
    21. </web-app>


      啟動Spring容器時,需要得到兩個信息:Spring配置文件的地址和Log4J屬性文件,這兩上信息分別通過contextConfigLocationWeb和log4jConfigLocation容器參數指定,如果有多個Spring配置文件,則用逗號隔開,如:

    /WEB-INF/applicationContext_1.xml, /WEB-INF/applicationContext_1.xm2

      由于在啟動ContextLoaderServlet之前,必須事先初始化Log4J的引擎,所以Log4jConfigServlet必須在ContextLoaderServlet之前啟動,這通過<load-on-startup>來指定它們啟動的先后順序。

      亂碼是開發Web應用程序一個比較老套又常見問題,由于不同Web應用服務器的默認編碼是不一樣的,為了方便Web應用在不同的Web應用服務器上移植,最好的做法是Web程序自身來處理編碼轉換的工作。經典的作法是在web.xml中配置一個編碼轉換過濾器,Spring就提供了一個編碼過濾器類CharacterEncodingFilter,下面,我們為應用配置上這個過濾器:

    1. <web-app>
    2. …
    3. <filter>
    4. <filter-name>encodingFilter</filter-name>
    5. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    6. <init-param>
    7. <param-name>encoding</param-name>
    8. <param-value>GBK</param-value>
    9. </init-param>
    10. </filter>
    11. <filter-mapping>
    12. <filter-name>encodingFilter</filter-name>
    13. <url-pattern>/*</url-pattern>
    14. </filter-mapping>
    15. …
    16. </web-app>


      Spring的過濾器類是org.springframework.web.filter.CharacterEncodingFilter,通過encoding參數指定編碼轉換類型為GBK,<filter-mapping>的配置使該過濾器截獲所有的請示。

      Struts的框架也需要在web.xml中配置,想必讀者朋友對Struts的配置都很熟悉,故在此不再提及,請參見本文所提供的源碼。

      總結

      本文通過一個文件上傳下載的Web應用,講解了如何構建基于SSH的Web應用,通過Struts和FormFile,Spring的LobHandler以及Spring為HibernateBlob處理所提供的用戶類BlobByteArrayType ,實現上傳和下載文件的功能僅需要廖廖數行的代碼即告完成。讀者只需對程序作稍許的調整,即可處理Clob字段:

      ·領域對象對應Clob字段的屬性聲明為String類型;

      ·映射文件對應Clob字段的屬性聲明為org.springframework.orm.hibernate3.support.ClobStringType類型。

      本文通過SSH對文件上傳下載簡捷完美的實現得以管中窺豹了解SSH強強聯合構建Web應用的強大優勢。在行文中,還穿插了一些分層的設計經驗,配置技巧和Spring所提供的方便類,相信這些知識對您的開發都有所裨益。

    作者:陳雄華出處:天極開發


    posted on 2008-04-10 15:03 阿偉 閱讀(365) 評論(0)  編輯  收藏 所屬分類: 框架整合
    主站蜘蛛池模板: 亚洲天堂免费在线视频| 人人揉揉香蕉大免费不卡| 亚洲国产精品自产在线播放| 免费精品视频在线| 亚洲视频在线一区| 国产免费人成在线视频| 91在线免费观看| 亚洲乱码在线播放| 国产精品亚洲综合一区| 亚洲免费在线视频观看| 黄色网址大全免费| 亚洲欧洲日本精品| 亚洲国产精品无码久久九九| 免费国产黄网站在线观看视频| 亚洲精品无码人妻无码| AV在线播放日韩亚洲欧| 国产在线观看免费观看不卡| 一个人免费观看视频在线中文| 亚洲酒色1314狠狠做| 亚洲av无码国产精品色在线看不卡| 久久久久国产免费| 黄网站色视频免费看无下截| 亚洲影院在线观看| 亚洲精品久久久www| 国产精品69白浆在线观看免费| 国产免费一区二区三区免费视频| 亚洲AV成人一区二区三区在线看 | 在线观看的免费网站| a免费毛片在线播放| 亚洲男人天堂2018av| 亚洲精品成人av在线| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 中文字幕亚洲综合久久| 亚洲人成电影在线播放| 毛片大全免费观看| 少妇太爽了在线观看免费视频| 深夜免费在线视频| 亚洲JLZZJLZZ少妇| 亚洲一区精彩视频| 亚洲精品日韩专区silk| 亚洲成AV人在线观看天堂无码|