1. 程式人生 > >struts2使用form表單無重新整理上傳檔案

struts2使用form表單無重新整理上傳檔案

這幾天在做專案時有用到一個form表單來上傳多個檔案,並且要求不能重新重新整理。當時在做的時候由於不是很瞭解這個東西,導致還是走了一些彎路的,現在把程式碼貼出來,供大家一起交流

html程式碼

<div id="book" style="display:none; background-color: #F3F3F3;text-align: center;margin-left: 15%;width: 80%;;border: 1;border-radius:15px ">
	<h3>書籍上傳</h3>
	<form  action="ResourceTypeAction_uploadFile.action" target="target" method="post" enctype="multipart/form-data" onsubmit="return toVaild1()">
	<input type="hidden" name="resourceTypeId" id="resourceTypeId1">
	<table style="text-align: center;width: 100%">
		<tr height="35px">
			<td width="33%" style="text-align: right;">類別:   </td>
			<td style="text-align: left;" colspan="2"><select id="category" class='select2' name='cid'>
							<option value="0">--請選擇--</option></select>  <span class="prompt">*</span></td>
		</tr>
		<tr height="35px">
			<td width="33%" style="text-align: center;" >ISBN: <input type="text" name="isbn" id="isbn"/><span class="prompt">*</span> </td>
			<td width="33%" style="text-align: left;">       書名: <input type="text" name="title" id="title"/> <span class="prompt">*</span> </td>
			<td width="33%" style="text-align: left;">       價格: $<input type="text" name="price" id="price"/>  </td>
		
		</tr>
		<tr height="35px">
			<td width="33%" style="text-align: center;">作者: <input type="text" name="author" id="author"/> </td>
			<td width="33%" style="text-align: center;">書籍圖片: <input type="file" name="imagesUrl" id="imagesUrl" accept="image/*"/> </td>
			<td width="33%" style="text-align: center;">書籍PDF:<input type="file" name="pdfsUrl" id="pdfsUrl1"/> <span class="prompt">*</span></td>
		</tr>
		<tr height="35px">
			<td width="33%" style="text-align: center;">              書籍原始碼:<input type="file" name="codesUrl" id="codesUrl1"/> </td>
			<td width="33%" ><input height="35px" type="submit" value="上傳" class="inp_L1" onMouseOver="this.className='inp_L2'" onMouseOut="this.className='inp_L1'"> </td>
		</tr>
		<tr>
		<td colspan="3" style="text-align: left;"><br>書籍描述:</br><textarea rows="30" cols="50" id="editor01" name="description"></textarea></td></tr>
	</table>
 	</form>
 	<iframe name="target" id="target" frameborder="0" width="0" height="0"></iframe>
</div>
這裡有幾個地方一定要注意一下

1.target="target"   表示表單在提交完資料後,處理的結果在target指定的iframe裡執行,同時我把iframe設定高度和寬頻都為0,這樣就達到了隱藏的效果,所以這麼做就能達到無重新整理的效果

2. onsubmit="return toVaild1()" 這個是表單在點選提交時,會進入toVaild1這個方法裡面來校驗資料,對於我們來控制提交的資料很有幫助的。一旦那個資料不符合我們的要求

,我們只需要返回一個false就行了,表單在你返回一個false後就不會提交了

3. enctype="multipart/form-data" 這個就不用多說了吧,檔案上傳必須來這麼個東西

toVaild1方法

function toVaild1(){
    var val = document.getElementById("category").value;
    
    if(val == "--請選擇--"){
        alert("請選擇一個類別");
        return false;
  }
}

在表單提交完資料,我們通過下面這個js程式碼來處理結果
<script>
//通過這個js提示檔案是上傳成功還是失敗
    var iframe = document.getElementById("target");
    var uploadCallback = function () {
        var data=iframe.contentDocument.body.innerHTML;
       // "<pre style="word-wrap: break-word; white-space: pre-wrap;">{"obj":"","responseCode":0}</pre>"
       var start=data.indexOf("responseCode");//
        var num=data.substring(start+14,start+15);//獲取響應碼
        if(num==1||num=="1"){
	alert("成功");
        }else{
        	alert("失敗")
        }
    };
    iframe.onload = uploadCallback;
</script>
上面這個js程式碼有個要注意的地方,那個responseCode不是固定的,是你自己封裝的狀態響應屬性!像我就是有寫這麼個javabean的,responseCode是響應狀態,obj是響應內容。所以下面那個擷取響應碼也是跟大家自己封裝的Javabean有關


下面就是action裡面處理這個表單資料了

	public void uploadFile() throws IOException {
		HttpServletRequest request = ServletActionContext.getRequest();
		String name=request.getParameter("pdfsUrl");
		String imagesUrlname=null;
		String pdfsUrlname=null;
		String codesUrlname=null;
		if(this.imagesUrl!=null && this.imagesUrl!=""){
				imagesUrlname=UploadFileUtil.uploadFile(request,new File(this.imagesUrl),this.imagesUrlFileName, "updloadBook");

		}
		if(this.pdfsUrl!=null && this.pdfsUrl!=""){
				pdfsUrlname=UploadFileUtil.uploadFile(request,new File(this.pdfsUrl),this.pdfsUrlFileName, "updloadBook");
		}
		if(this.codesUrl!=null && this.codesUrl!=""){
				codesUrlname=UploadFileUtil.uploadFile(request,new File(this.codesUrl),this.codesUrlFileName, "updloadBook");
		}
		Book book=new Book();
		book.setAuthor(author);
		book.setCid(cid);
		book.setIsbn(isbn);
		book.setTitle(title);
		book.setPrice(price);
		book.setDescription(description);
		book.setPdfsUrl(pdfsUrlname);
		book.setImagesUrl(imagesUrlname);
		book.setCodesUrl(codesUrlname);
		book.setResourceTypeId(resourceTypeId);
		book.setEdtionId(edtionId);
		book.setSubjectid(subjectid);
		book.setSemeter(semeter);
		this.resourceTypeBiz.insertInfo(book);
		jsonStr = super.writeJson(1, "成功");
		try {
		} catch (Exception e) {
			jsonStr = super.writeJson(0, "失敗");
			logger.error(e);
		}
		JsonUtil.jsonOut(jsonStr);
	}

說到這裡就要說Struts2框架裡面有個這麼的東西了,在檔案上傳後,提交到後臺的檔案其實是個臨時檔案,那麼我們想獲得檔案的型別和檔名想通過前臺傳過來的檔案來獲取這就是不可能的了,因為在臨時檔案中是得不到這些東西的,所以Struts2框架給我們提供了
// <!--獲取上傳檔名,命名格式:表單file控制元件名+FileName(固定)-->    
    private String imagesUrlFileName;
這麼東西,它的格式是固定的,只需要在action的屬性裡面加上一個file的name值+FileName就行了,它就能在表單提交後自動注入提交的檔名,除此之外,Struts1還有提供一個獲取檔案型別的東西
 //獲取上傳檔案型別,命名格式:表單file控制元件名+ContentType(固定) 
    private String imagesUrlContentType; 
通過上面的程式碼我們也看到了,我有呼叫了一個工具類的方法,

下面就是那個工具類的方法

public class UploadFileUtil {

	/**
	 * 
	 * @param request http請求,用來獲取伺服器的路徑
	 * @param file 要儲存的臨時檔案
	 * @param fileName 要上傳檔案的原來名字
	 * @param picRootName 要上傳檔案儲存在webapps下面那個資料夾下
	 * @author Administrator 
	 * @return
	 */
	public static String uploadFile(HttpServletRequest request,File file, String fileName,String picRootName) {
		String newFileUrl=null;
		Map<String, UploadFile> map = new HashMap<String, UploadFile>();
			
			//  request.getSession().getServletContext().getRealPath("/") =>   C:\tomcat\apache-tomcat-7.0.47\webapps\douban
			// getParentFile() =>   E:\apache-tomcat-8.0.44-windows-x64\apache-tomcat-8.0.44\webapps  
			File webappsfile = new File(request.getSession().getServletContext().getRealPath("/")).getParentFile();
			

			File picFile = new File(webappsfile, picRootName);
			
			
			String picBasePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
					+ "/" + picRootName;
			String originalFilename=fileName;
			
					// 生成新檔名,與時間相關
					String newfilename = getUniqueFileName()
							+ originalFilename.substring(originalFilename.lastIndexOf("."));
					String saveDir = picFile.getAbsolutePath() + getNowDateStr();
					String newFilePath = saveDir + newfilename;
					
					// http://localhost:8080/updloadBook/2017/8/22/**.txt
					newFileUrl = picBasePath + getNowDateStr() + newfilename;
					
					File saveDirFile = new File(saveDir);

					if (!saveDirFile.exists()) {
						saveDirFile.mkdirs();
					}
					String path=saveDir+ java.io.File.separator+newFileUrl;
				
			        try {
						//輸出流  http://localhost:8080/updloadBook/2017/8/22/3413dba067d74a37b7e7e11060dcab03.tmp
						OutputStream os = new FileOutputStream(newFilePath);  
						//輸入流  
						InputStream is = new FileInputStream(file);  
						  
						byte[] buf = new byte[1024];  
						int length = 0 ;  
						  
						while(-1 != (length = is.read(buf) ) )  
						{  
						    os.write(buf, 0, length) ;  
						}  
						is.close();  
						os.close();
					} catch (IOException e) {
						
						e.printStackTrace();
					}  
	
		return newFileUrl;
	}

	/**
	 * 如果一個資料夾下面儲存超過1000個檔案,就會影響檔案訪問效能,所以上傳的檔案要分散儲存, 這裡用年月日作為目錄層級 * 獲取當前日期字串
	 * * @param separator * @return "/2017/2/20/"
	 */
	private static String getNowDateStr() {
		Calendar now = Calendar.getInstance();
		int year = now.get(Calendar.YEAR);
		int month = now.get(Calendar.MONTH) + 1;
		int day = now.get(Calendar.DATE);
		
		//          /                        /                       /
		//return File.separator + year + File.separator + month + File.separator + day + File.separator;
		return "/"+year+"/"+month+"/"+day+"/";
	}

	/**
	 * 生成唯一的檔名
	 * 
	 * @return
	 */
	private static String getUniqueFileName() {
		String str = UUID.randomUUID().toString();   //444ffdd-333dd -666-666
		return str.replace("-", "");
	}

}
就這樣,檔案就上傳成功了,並且通過前臺的那個處理表單提交的js來得知檔案是否上傳成功和失敗了!