bboss mvc檔案上傳下載下傳新增功能詳解
1.概述
最近對bboss mvc的檔案上傳和下載下傳功能做了以下改造:
a.檔案上傳插件增加對html5檔案上傳功能的支援-application/octet-stream請求的處理
b.檔案上傳插件增加IgnoreFieldNameMultipartFile接口
c.檔案下載下傳
org.frameworkset.http.converter.FileMessageConvertor插件支援下載下傳Resource接口對應的資源
下面詳細介紹每一部分。
2.html5檔案上傳功能
html5檔案上傳時對應的mime類型可以為application/octet-stream,之前的檔案上傳插件是不支援application/octet-stream類型的附件的處理的,是以對上傳插件進行修改進而支援這種類型的附件的處理,目前支援單次一個附件的處理,服務端的處理方式沒有改變,請參考另外兩篇附件處理的文章。為了測試該功能,在火狐浏覽器下使用xheditor-1.1.13線上編輯器的檔案上傳執行個體demo08.html功來示範該功能,xheditor-1.1.13已經內建到bbossgroups的最佳實踐工程
demoproject中,對應的jsp檔案為:
/demoproject/WebRoot/xheditor/demos/demo08.jsp
下載下傳該demoproject導入eclipse并部署到tomcat在火狐浏覽器中輸入(xheditor自動将上傳類型定義為application/octet-stream,ie還是以傳統的form multidata方式送出)
http://localhost:8080/WebRoot/xheditor/demos/demo08.jsp即可點選裡面的圖檔上傳功能檢視效果,這裡我們隻看看一下demo08.jsp中和檔案上傳相關的代碼:
<link rel="stylesheet" href="common.css" type="text/css" media="screen" />
<script type="text/javascript" src="../jquery/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="../xheditor-1.1.13-zh-cn.min.js"></script>
<script type="text/javascript">
$(pageInit);
function pageInit()
{
$.extend(xheditor.settings,{shortcuts:{'ctrl+enter':submitForm}});
$('#elm1').xheditor({upLinkUrl:"<%=request.getContextPath()%>/file/upload.page",upLinkExt:"zip,rar,txt",upImgUrl:"<%=request.getContextPath()%>/file/uploadwithbean.page?testparam=中文",upImgExt:"jpg,jpeg,gif,png",upFlashUrl:"<%=request.getContextPath()%>/file/upload.page",upFlashExt:"swf",upMediaUrl:"<%=request.getContextPath()%>/file/upload.page",upMediaExt:"wmv,avi,wma,mp3,mid"});
$('#elm2').xheditor({upLinkUrl:"<%=request.getContextPath()%>/file/upload.page?immediate=1",upLinkExt:"zip,rar,txt",upImgUrl:"<%=request.getContextPath()%>/file/upload.page?testparam=test&immediate=1",upImgExt:"jpg,jpeg,gif,png",upFlashUrl:"<%=request.getContextPath()%>/file/upload.page?immediate=1",upFlashExt:"swf",upMediaUrl:"<%=request.getContextPath()%>/file/upload.page?immediate=1",upMediaExt:"wmv,avi,wma,mp3,mid"});
$('#elm3').xheditor({upLinkUrl:"<%=request.getContextPath()%>/file/upload.page",upLinkExt:"zip,rar,txt"});
$('#elm4').xheditor({upImgUrl:"<%=request.getContextPath()%>/file/upload.page",upImgExt:"jpg,jpeg,gif,png"});
$('#elm5').xheditor({upFlashUrl:"<%=request.getContextPath()%>/file/upload.page",upFlashExt:"swf",upMediaUrl:"<%=request.getContextPath()%>/file/upload.page",upMediaExt:"wmv,avi,wma,mp3,mid"});
$('#elm6').xheditor({upLinkUrl:"<%=request.getContextPath()%>/file/upload.page",upLinkExt:"zip,rar,txt",upImgUrl:"<%=request.getContextPath()%>/file/upload.page",upImgExt:"jpg,jpeg,gif,png",onUpload:insertUpload});
}
服務端處理方法為(\bestpractice\demoproject\src\org\frameworkset\mvc\FileController.java):
public @ResponseBody String upload(IgnoreFieldNameMultipartFile filedata,String testparam) throws IllegalStateException, IOException
{
if(filedata != null)
{
//将附件存入d盤下的檔案tst.png
filedata.transferTo(new File("d:/tst.png"));
}
return "{\"err\":\"\",\"msg\":\"tst.png\"}";
}
upload方法可以接收html5上傳的附件也可以接收html4 傳統表單方式上傳的附件,是以屏蔽了html版本的差異性。upload方法兩個參數:
IgnoreFieldNameMultipartFile filedata 包含上傳的附件正文和附加資訊,IgnoreFieldNameMultipartFile 類型為新加的接口類型,和MultipartFile類型的差別下節詳細介紹。
String testparam 上傳時指定的一個額外參數用來展示html4和html5中,随同附件一起送出的普通參數都能被bboss 的檔案上傳插件正常處理。
3.IgnoreFieldNameMultipartFile接口
IgnoreFieldNameMultipartFile 類型為新加的接口類型,它和之前的MultipartFile接口類型的差別在這裡做詳細介紹。
IgnoreFieldNameMultipartFile接口是MultipartFile接口的子類,IgnoreFieldNameMultipartFile沒有新加任何方法,之是以添加IgnoreFieldNameMultipartFile接口的原因為:MultipartFile接口類型對應的控制器方法參數名稱或者bean屬性名稱必須和對應的表單input[file]元素的name保持一緻(或者必須通過@RequestParam注解來指定控制器方法參數或者bean屬性和input[file]元素的name的映射關系),這對應一般的表單問題不大,因為可以明确地知道表單中file input元素的名稱。但是對于第三方檔案上傳控件(例如swfupload,或者xheditor之類的插件)我們無法明确知道file input的name屬性的值,是以無法通過input的名稱和控制器方法參數或者bean屬性進行值注入綁定。對于這種情況有兩種處理辦法,一種是采用比較原始的MultipartHttpServletRequest 對象來擷取并處理所有的附件資訊:
public void uploadFile(MultipartHttpServletRequest request,
ModelMap model, @RequestParam(name = "upload_")
String upload_) {
Iterator<String> fileNames = request.getFileNames();
List<UpFile> files = new ArrayList<UpFile>();
File dir = new File("d:/mutifiles/");
if(!dir.exists())
dir.mkdirs();
while (fileNames.hasNext()) {
String name = fileNames.next();
MultipartFile file = request.getFile(name);
String temp = file.getOriginalFilename();
try {
file.transferTo(new File("d:/mutifiles/" + temp));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
UpFile uf = new UpFile();
uf.setFileName(temp);
uf.setFileType(file.getContentType());
files.add(uf);
}
model.addAttribute("files", files);
}
第二種方式就是本文介紹的方式,借助于新的IgnoreFieldNameMultipartFile接口來處理:
public @ResponseBody String upload(IgnoreFieldNameMultipartFile[] files,String testparam) throws IllegalStateException, IOException
{
if(filedata != null)
{
filedata[0].transferTo(new File("d:/tst.png"));
}
return "{\"err\":\"\",\"msg\":\"tst.png\"}";
}
我們将附件參數files的類型指定為IgnoreFieldNameMultipartFile或者IgnoreFieldNameMultipartFile[],明确地告訴mvc忽略控制器方法參數或者bean屬性與input file元素的name值進行名稱映射綁定,直接将上傳的附件對象作為控制器方法參數或bean屬性的值注入,不管表單送出了多少個input file元素,會将所有input file元素的對應的附件或者附件數組注入到控制器方法參數或者bean屬性中,這就是引入IgnoreFieldNameMultipartFile類型的目的,隻要控制器方法參數或者bean屬性的類型為IgnoreFieldNameMultipartFile,那麼就按這個規則來進行控制器方法參數值或者bean屬性值綁定。
4.org.frameworkset.http.converter.FileMessageConvertor插件支援下載下傳Resource接口對應的資源
FileMessageConvertor插件除了任然支援File對象和Blob對象的下載下傳外,新增了Resource類型資源的下載下傳,包括以下類型:
ClassPathResource -- 适用于應classpath下面的各種資源
ServletContextResource --适用于web應用根目錄及子目錄下的各種資源
FileSystemResource --适用于檔案系統中各種檔案資源
UrlResource --适用于url連接配接對應各種資源
ByteArrayResource--适用于二進制資源
我們以ClassPathResource 為例來說明具體的使用方法如下:
public @ResponseBody
Resource exportExeclTemplate() throws Exception {
String fileName = "com/sany/mms/background/action/exceldata.xls";
ClassPathResource classpath = new ClassPathResource(fileName);
return classpath;
}
5.FileBlob的使用
FileBlob對象主要是用來直接下載下傳Blob對象和InputStream流對象,同時可以指定一個下載下傳檔案名,執行個體如下:
public @ResponseBody
FileBlob exportExeclTemplate() throws Exception {
String fileName = "com/sany/mms/background/action/exceldata.xls";
FileBlob fb = new FileBlob ("exceldata.xls",new FileInputstream(new File(fileName)))//下載下傳檔案流
FileBlob fb = new FileBlob ("exceldata.xls",Blob對象) //下載下傳blob流
FileBlob fb = new FileBlob ("test.xml",new URL("http://localhost:8080/bboss/test.xml"));//下載下傳url位址對應的資源
return fb;
}
到此,各個部分介紹完畢,如果有不妥之處,歡迎大家批評指正。