1. 程式人生 > >Strut2 和Spring MVC 文件上傳對比

Strut2 和Spring MVC 文件上傳對比

string num control 需要 nsf ping types quest nal

在Java領域中,有兩個常用的文件上傳項目:一個是Apache組織Jakarta的Common-FileUpload組件 (http://commons.apache.org/proper/commons-fileupload/),另一個是Oreilly組織的COS框架的 (http://www.servlets.com/cos)。

1.Struts2的文件上傳

Struts2本身並沒提供上傳的組件,我們可以通過調用上傳框架來實現文件的上傳,struts2默認是jakarta作為其文件上傳的解析器。

jakarta是Commo-FileUpload的框架。如果要使用Commo-FileUpload框架來上傳文件,只需將"commons-fileupload-1.2.1.jar"

和"commons-io-1.3.2.jar"兩個jar復制到項目中的WEB-INF/lib目錄下就可。我們這裏上傳就是基於Commo-FileUpload框架實現的。

首先我們建立一個上傳的JSP頁面:

技術分享
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> 
<head>  
    <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">       
<title>文件上傳</title>  
</head>  
<body>  
<form action="upload.action" method="post" enctype="multipart/form-data">  

  <input type="file" name="file" /> 
  <input type="submit" value="Submit" />

</form>  
</body>  
</html>
技術分享

下面我們順便介紹一下from 中enctype屬性的含義:

表單元素的enctype屬性指定的是表單數據的編碼方式,該屬性有3個值:   1) application/x-www-form-urlencoded:這是默認編碼方式,它只處理表單域裏的value屬性值,采用這種編碼方式的表單會將表單域的 值處理成URL編碼方式。   2) multipart/form-data:這種編碼方式的表單會以二進制流的方式來處理表單數據,這種編碼方式會把文件域指定文件的內容也封裝到 請求參數裏。   3) text/plain:這種方式主要適用於直接通過表單發送郵件的方式。   文件上傳是原理是通過為表單元素設置enctype=”multipart/form-data”屬性,讓表單提交的數據以二進制編碼的方式提交, 在接收此請求的Servlet中用二進制流來獲取內容,就可以取得上傳文件的內容,從而實現文件的上傳。 在我們建立upload.action之前先對struts.xml進行相應的設置,如下所示: 技術分享
    <constant name="struts.multipart.maxSize" value="10701096"/>
    <!-- 設置上傳文件的臨時文件夾,默認使用javax.servlet.context.tempdir -->
    <constant name="struts.multipart.saveDir " value="c:/temp" />
    <!--靜態屬性設置添加以上設置-->
    
    <package name="upload" extends="struts-default">
        <action name="upload" class="com.test.action.UploadAction" method="execute">
            <!-- 動態設置savePath的屬性值 -->
            <param name="savePath">/upload</param>
            <result name="success">/WEB-INF/success.jsp</result>
            <result name="input">/upload.jsp</result>
            <interceptor-ref name="fileUpload">
                <!-- 文件過濾 -->
                <param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>
                <!-- 文件大小, 以字節為單位 -->
                <param name="maximumSize">1025956</param>
            </interceptor-ref>
            <!-- 默認攔截器必須放在fileUpload之後,否則無效 -->
            <interceptor-ref name="defaultStack" />
        </action>
    </package>
技術分享

Upload.action:

技術分享
public class UploadAction extends ActionSupport {
private File file;//對應文件域和頁面中file input的name保持一致 private String fileContentType;//前面的File屬性的名字 + ContentType(固定的) private String fileFileName;//前面的File屬性的名字 + FileName(固定的) private String savePath;//保存路徑 @Override public String execute() { FileOutputStream fos = null; FileInputStream fis = null; try { // 建立文件輸出流 fos = new FileOutputStream(getSavePath() + "\\" + getFileFileName()); // 建立文件上傳流 fis = new FileInputStream(getFile()); byte[] buffer = new byte[1024]; int len = 0; while ((len = fis.read(buffer)) > 0) { fos.write(buffer, 0, len); } } catch (Exception e) { System.out.println("文件上傳失敗"); e.printStackTrace(); } finally { fis.close(); fos.close(); } return SUCCESS; } /** * 返回上傳文件的保存位置 * * @return */ public String getSavePath() throws Exception{ return ServletActionContext.getServletContext().getRealPath(savePath); } public void setSavePath(String savePath) { this.savePath = savePath; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public String getFileContentType() { return fileContentType; } public void setFileContentType(String fileContentType) { this.fileContentType = fileContentType; } public String getFileFileName() { return fileFileName; } public void setFileFileName(String fileFileName) { this.fileFileName = fileFileName; } }
技術分享

最後順便說一下上傳多個文件,主要有以下兩種方式:

1.數組

File[] file 文件
String[] fileFileName 文件名
String[] fileContentType 文件類型

2.集合

List<File> file
List<String> fileFileName
List<String> fileContentType

2.SpringMVC的文件上傳

個人認為Spring mvc的文件上傳要比struts2要方便多了。Spring mvc 支持web應用程序的文件上傳功能,是由Spring內置的即插即用的MultipartResolver來實現的,

上傳的時候就需要在Spring的ApplicationContext裏面加上SpringMVC提供的MultipartResolver的聲明。這樣之後,客戶端每次進行請求的時候,

SpringMVC都會檢查request裏面是否包含多媒體信息,如果包含了就會使用MultipartResolver進行解析,SpringMVC會使用一個支持文件處理的

MultipartHttpServletRequest來包裹當前的HttpServletRequest,然後使用MultipartHttpServletRequest就可以對文件進行處理了。

Spring MVC已經為我們提供了一個MultipartResolver的實現,我們只需要拿來用就可以了,那就是org.springframework.web.multipart.commons.CommsMultipartResolver。因為springMVC的MultipartResolver底層使用的是Commons-fileupload,所以還需要加入對Commons-fileupload.jar的支持。 首先我們還是要建立一個上傳頁面: 技術分享
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> 
<head>  
    <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">       
<title>文件上傳</title>  
</head>  
<body>  
<form action="upload.do" method="post" enctype="multipart/form-data">  

  <input type="file" name="file" /> 
  <input type="submit" value="Submit" />

</form>  
</body>  
</html>
技術分享

然後我們在SpringMVC的applicationContent配置文件中加入以下設置:

技術分享
    <!-- 上傳文件 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="utf-8" /> 
    <!-- 以字節為單位的最大上傳文件的大小 -->  
    <property name="maxUploadSize" value="100000" /> 
    </bean>
技術分享

CommonsMultipartResolver允許設置的屬性有:
defaultEncoding:表示用來解析request請求的默認編碼格式,當沒有指定的時候根據Servlet規範會使用默認值ISO-8859-1。

當request自己指明了它的編碼格式的時候就會忽略這裏指定的defaultEncoding。

uploadTempDir:設置上傳文件時的臨時目錄,默認是Servlet容器的臨時目錄。
maxUploadSize:設置允許上傳的最大文件大小,以字節為單位計算。當設為-1時表示無限制,默認是-1。
maxInMemorySize:設置在文件上傳時允許寫到內存中的最大值,以字節為單位計算,默認是10240。

創建一個controller(控制器)來處理文件上傳請求,FileUploadController.java:

實現上傳的方法如下:

@RequestMapping( value="/upload.do",method = { RequestMethod.POST }) public ModelAndView upload(@RequestParam(value = "file", required = false) MultipartFile file,HttpServletRequest request) {<br> System.out.println("開始"); String path = request.getSession().getServletContext().getRealPath("upload");//上傳的目錄 String fileName = file.getOriginalFilename();//上傳的文件名字 System.out.println(path); File targetFile = new File(path, fileName); if (!targetFile.exists()) { targetFile.mkdirs(); } // 保存 try { file.transferTo(targetFile); } catch (Exception e) { e.printStackTrace(); } return new ModelAndView("result"); }

Strut2 和Spring MVC 文件上傳對比