1. 程式人生 > >springboot框架下的上傳下載

springboot框架下的上傳下載

專案接觸到新的框架技術:springboot+angularjs+bootstrap 其中稍微有點難度的就屬於上傳下載了

1,上傳檔案


前端樣式如上所示,點選"匯入模板檔案",瀏覽選擇檔案,點選“匯入”則上傳檔案資訊到伺服器,當上傳成功後,在右側顯示檔名,並且提供下載功能。

上傳樣式

<span style="font-size:18px;">	<div class="row">
			<div class="col-md-12">
				<form name="newDeviceType" class="form-inline" role="form">
					<div style="width: 100%; height: 20px; background-color: #E0ECFB">廠商模板檔案</div>
					<table class="table table-hover table-bordered">
						<tr>
							<td>
								<div style="margin-left: 15px;"  flow-init="addFlowInitObjModel" class="col-md-8" flow-file-success="uploadSuccess( $file, $message, $flow )">
								  <span class="btn btn-small btn-info" flow-btn flow-attrs="{accept:'application/xml'}">匯入模板檔案</span>
									<span class="btn btn-small btn-info" ng-click="$flow.upload()">
									匯入</span>
									<div ng-repeat="file in $flow.files" class="transfer-box">
								        <span ng-if="file.progress() !== 1">{{file.relativePath}} ({{file.size}}bytes)</span>
								        <div class="progress progress-striped" ng-class="{active: file.isUploading()}" ng-if="file.progress() !== 1">
								            <div class="progress-bar" role="progressbar"
								                 aria-valuenow="{{file.progress() * 100}}"
								                 aria-valuemin="0"
								                 aria-valuemax="100"
								                 ng-style="{width: (file.progress() * 100) + '%'}">
								        <span class="sr-only">{{file.progress()}}% Complete</span>
							            </div>
							        </div>
							    </div>
							    
							</div>
								
							</td>
							<td>
								<div >
							    	點選下載檔案<a style="hidden" href="" ng-click = "downloadFile()" id="filename"></a>
							    </div>
							</td>
						</tr>
					</table>
				</form>
			</div>
		</div></span>

這個控制元件在初始化的時候flow-init=“addFlowInitObjModel”,去載入請求路徑
<span style="font-size:18px;"> // 上傳模板檔案
    $scope.addFlowInitObjModel = {    	
            target: '/deviceType/importFile',
            //target: '/deviceType/importFile',
            chunkSize: 1 * 1024 * 1024,
            simultaneousUploads: 1,
            throttleProgressCallbacks: 1,
            testChunks: false,
            singleFile: true
        };</span>

之後點選上傳的時候會發送到後臺請求:ng-click="$flow.upload()"

angularjs提供了上傳之後成功之後的操作函式:flow-file-success="uploadSuccess( $file, $message, $flow )"

$file :上傳的檔案,可以獲得該檔案的大小($file.size),檔名($file.name)等檔案相關的引數

$message :後臺返回的資料資訊(在這裡需要用到後臺返回的上傳檔案的路徑資訊,只要後臺return 路徑,前端就可以使用$message,至於flow沒用到)

後臺處理的方法就是,讀取檔案流,然後將流寫入到檔案中就行,最後儲存檔案到指定的地方。

<span style="font-size:18px;">/**
	 * 上傳模板檔案並解析儲存到本地
	 * @throws IOException 
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 */
	@RequestMapping(value="/importFile",method=RequestMethod.POST)
	public String importLicense(MultipartHttpServletRequest req) throws Exception{
		try{
			//long modelId = Long.parseLong(req.getParameter("id"));
			// 讀取流
			StringBuffer strBuff = new StringBuffer();
			InputStream in = req.getFile("file").getInputStream();		
			Reader in2 = new InputStreamReader(in);
			BufferedReader reader = new BufferedReader(in2);
			String line = null;
			while ((line = reader.readLine()) != null) {
				strBuff.append(line);
			}	
			String ldbstr = strBuff.toString();
			in.close();
			System.out.println(ldbstr);
			
			// 建立檔案儲存路徑
			File file =new File(FILE_PATH);  
			//如果資料夾不存在則建立  
			if  (!file .exists()  && !file .isDirectory())    
			{     
			    System.out.println("//不存在");
			    file .mkdir();  
			} else 
			{
			    System.out.println("//目錄存在");
			}
			String filePath = FILE_PATH+"\\2.xml";
		    File fileName=new File(filePath);  
		    if(!file.exists())   {  
		    	fileName.createNewFile();  
		    }  
		    // 寫入到檔案中
		    OutputStream os = new FileOutputStream(fileName);  
            os.write(ldbstr.getBytes());  
            os.flush();  
            os.close();  
                        
            // 修改資料庫中版本型別對應的模板檔案地址
//            DeviceType type =  deviceTypeService.findOne(id);            
//            type.setTemplateFilePath(filePath);
//            deviceTypeService.update(type);
			return filePath;		
		}catch(Exception e){
			e.printStackTrace();
			return "";
		}
		
	}</span>

由於需要路徑引數,就需要返回到前端進行資料繫結(如果你只需要上傳,則不需要)
<span style="font-size:18px;"> // 模板檔案上傳成功之後,返回檔案路徑,將路徑儲存到資料庫中,同時顯示上傳檔名稱,提供下載連結
    $scope.uploadSuccess = function ($file, $message, $flow){
    	var deviceType = $scope.deviceTypeManager.currentDeviceType;
    	deviceType.templateFilePath = $message;
    	deviceType.put();    	
    	document.getElementById("filename").innerHTML = $file.name;//制定位置顯示檔名稱
    }</span>

2,檔案下載

下載比較簡單,只要有路徑就行。同樣需要讀流,然後write到前端就行,在這裡使用了iframe來處理下載

<span style="font-size:18px;">// 上傳模板檔案下載
    $scope.downloadFile = function (){
    	var typeId = $scope.deviceTypeManager.currentDeviceType.id;
    	//$scope.deviceTypeManager.currentDeviceType.get("/deviceType/downloadmcode?id="+typeId);
    	//target: '/versionFile/downloadmcode?id = '+ typeId;
//    	$http.get('/deviceType/downloadmcode', {
//    	    params: { id: typeId }
//    	});
    	
    	var frame = $("<iframe style='display: none;'/>");
        frame.appendTo($("body")).attr({ "src": "/deviceType/downloadmcode?id="+typeId, "display": "block" });
        setTimeout(function () {
            frame.remove();
        }, 3000);
    }</span>

其中src就是後臺請求路徑:
<span style="font-size:18px;">/**
	 * 下載
	 */
	@RequestMapping(value="/downloadmcode",method=RequestMethod.GET)
	public void downloadMcode(HttpServletResponse response,@RequestParam Long id){
		try {
			System.out.println("-------------------------------下載版本檔案對應裝置型別id="+id+"------------------------------------");
			DeviceType dt = deviceTypeService.findByid(id);
			String filePath = dt.getTemplateFilePath();// 檔案路徑
			String [] fp =   filePath.split("\\\\");
			String fileName = fp[fp.length-1];// 檔名稱
			System.out.println("-------------------------------上傳檔名為="+fileName);
			
			//下載機器碼檔案
			response.setHeader("conent-type", "application/octet-stream");
			response.setContentType("application/octet-stream");
			response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("ISO-8859-1"), "UTF-8"));
			
			OutputStream os = response.getOutputStream();
			BufferedOutputStream bos = new BufferedOutputStream(os);
			
			InputStream is = null;

			is = new FileInputStream(filePath);
			BufferedInputStream bis = new BufferedInputStream(is);

			int length = 0;
			byte[] temp = new byte[1 * 1024 * 10];

			while ((length = bis.read(temp)) != -1) {
				bos.write(temp, 0, length);
			}
			bos.flush();
			bis.close();
			bos.close();
			is.close();			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}</span>

這樣在chrome裡面就可以看到下方的下載情況了
<pre name="code" class="html">