天天看點

開發日常小結(10):項目如何使用圖檔伺服器API?

2018年4月13日

營運姐姐來需求,想上傳圖檔(活動推薦)給手遊玩家,不然怎麼推廣和賺錢呢??經過努力,還是完成了,如下圖所示:

開發日常小結(10):項目如何使用圖檔伺服器API?
開發日常小結(10):項目如何使用圖檔伺服器API?

【1】寫個頁面:添加檔案

并不難,下面提供一個執行個體(js):

<form class="form-horizontal" role="form" enctype="multipart/form-data" id="fileUploadForm" method="POST" action="${contextPath}/activity/addActivity">
					<table class="tableOne">
						<tr class="b-b-dc">
							<td class="width_150 padding-20 text-color-333 f16 text_center">活動資訊</td>
							<td class="padding-20"><div class="b-r-dc height_90"></div></td>
							<td>
								<div class="alert alert-warning" align="left">
								提醒:<br>
								<br>1.活動的展示順序由seq決定次序(seq越小,展示越早);<br>
								<br>2.若seq相同,則釋出時間決定次序(釋出時間越早,展示越早);<br>
								<br>3.活動的跳轉類型項請根據實際情況選擇;<br>
								<br>4.活動圖檔限制的上傳格式為:寬度最大為 714,高度不限制,建議 483;
								</div>
								<div class="tableTwoDiv">
									<table class="tableTwo">							
										<tr>
											<td class="text_right width_130">活動名稱:</td>
											<td>
												<input type="text"  autocomplete="off" class="form-control" id="name" name="name" placeholder="請輸入活動名" value="" >								
											</td>
										</tr>
										<tr>
											<td class="text_right width_130">排序(seq):</td>
											<td>
												<input type="text"  autocomplete="off" class="form-control" id="seq" name = "seq" placeholder="請輸入seq" value="" >							
											</td>
										</tr>
										<tr>
											<td class="text_right width_130">開始時間:</td>
											<td>
												<input type="text" class="form-control" id="startTime" name="startTime" placeholder="活動開始時間" value="" >							
											</td>
										</tr>
										<tr>
											<td class="text_right width_130">結束時間:</td>
											<td>
												<input type="text"  class="form-control" id="endTime" name="endTime" placeholder="活動結束時間" value="" >						
											</td>
										</tr>
										<tr>
											<td class="text_right width_130">跳轉連結:</td>
											<td>
												<input type="text"  autocomplete="off" class="form-control" id="toUrl" name="toUrl" placeholder="活動跳轉連結" value="">						
											</td>
										</tr>
										
										<tr>
											<td class="text_right width_130">跳轉類型:</td>
											<td>
	    										<select id="urlType" name="urlType" class="from-input">
													 <c:forEach var="turnUrlList" items="${turnUrlList }">
														<option value="${turnUrlList.urlTypeValue }">${turnUrlList.urlType }</option>
													 </c:forEach>
												</select>
											</td>
										</tr>
										
										<tr>
											<td class="text_right width_130">釋出時間:</td>
											<td>
												<input type="text" class="form-control" id="postTime" name="postTime" placeholder="選擇釋出時間" value="">						
											</td>
										</tr>
										
										<tr>
											<td class="text_right width_130">活動圖檔:</td>
											<td>
	    										<input type="file" id="fileUpload" name="pic" οnchange="jsReadFiles(this.files)">
												<!-- <input type="text" class="form-control" id="imgUrl" placeholder="http://" value=""> -->
											</td>
										</tr>
										
									</table>
								</div>										
							</td>
						</tr>	
					</table>		
				</div>
				<div class="form-group height_80 m-t-20 m-l-100 m-b-50">
					<div class="col-sm-1 m-l-185">
						<a id="submitFrom" class="btn-defeult" οnclick="edOpt.submitForm()">确認添加</a>
					</div>		
				</div>
				</form>
           

【2】擷取檔案流

<script type="text/javascript">
					//js 讀取圖檔檔案,限制長度寬度
				    function jsReadFiles(files) {
				    	var width = 0;
				    	var height = 0;
				        if (files.length) {
				            var file = files[0];
				          	//alert("**********"+file.size);
				          	//讀取圖檔資料
			                var reader = new FileReader();
			                reader.onload = function (e) {
			                    var data = e.target.result;
			                    //加載圖檔擷取圖檔真實寬度和高度
			                    var image = new Image();
			                    image.οnlοad=function(){
			                    	width  = image.width;
			                    	height = image.height;
			                    	if(width != 714){
							        	basic.alert("圖檔格式錯誤,上傳尺寸的寬度必須為714,請重新上傳圖檔!");
								        $("#fileUpload").val(null);
			                    		return ;
			                    	}else if(width == 714){
			                    		if(height != 0){
									    	basic.alert("格式正确,圖檔上傳成功!");  
			                    		}
			                    	}
			                    };
			                    image.src= data;
			                };
			                reader.readAsDataURL(file);
			            }
				    }	
           
                    </script >
           

【3】上傳表單:form表單

                                    submitForm:function(){
						var name = $("#name").val();
						
						if(name == ""){
							basic.message.topMessage("活動名稱不為空!");
							return;
						};
				
						$("#fileUploadForm").submit();
						//請求位址
						/* var ajaxUrl = "${contextPath}/activity/addActivity" ;*/
					},
           

【4】重點1:Multipart檔案接收

protected List<FileItem> fileItemList = null;		//上傳檔案項   
/**
	 * 從檔案上傳請求中擷取普通參數
	 * @return 包含請求參數的map集合.檔案上傳項可從父類屬性擷取
	 */	
	protected Map<String, String> getParamsFromMultipartRequest(HttpServletRequest request){
		Map<String, String> params = new HashMap<>();
		try{
            //1、建立一個DiskFileItemFactory工廠  
            DiskFileItemFactory factory = new DiskFileItemFactory();  
            //2、建立一個檔案上傳解析器  
            ServletFileUpload upload = new ServletFileUpload(factory);  
            //解決上傳檔案名的中文亂碼  
            upload.setHeaderEncoding("UTF-8");   
            //3、判斷送出上來的資料是否是上傳表單的資料  
            if(!ServletFileUpload.isMultipartContent(request)){  
                //按照傳統方式擷取資料  
            	this.sendFailMsg("上傳檔案失敗");
            }  
           //4、使用ServletFileUpload解析器解析上傳資料,解析結果傳回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項  
           List<FileItem> list = upload.parseRequest(request);  
           for(FileItem item : list){  
               //如果fileitem中封裝的是普通輸入項的資料  
               if(item.isFormField()){  
                   String fname = item.getFieldName(); 
                   String value = item.getString("UTF-8");  
                   if("".equals(fname)){
                	   continue;
                   }
                   params.put(fname, value);
                   //解決普通輸入項的資料的中文亂碼問題  
                   //value = new String(value.getBytes("iso8859-1"),"UTF-8");  
	            }else{//如果fileitem中封裝的是上傳檔案  
	                   //得到上傳的檔案名稱,
	            	if(fileItemList == null){
	            		fileItemList = new ArrayList<>();
	            	}
                   String filename = item.getName();  
                   if(filename==null || filename.trim().equals("")){  
                       continue;  
                   }
                   
                  //注意:不同的浏覽器送出的檔案名是不一樣的,有些浏覽器送出上來的檔案名是帶有路徑的,如:  c:\a\b\1.txt,而有些隻是單純的檔案名,如:1.txt  
                  //處理擷取到的上傳檔案的檔案名的路徑部分,隻保留檔案名部分  
                  //擷取item中的上傳檔案的輸入流
                   fileItemList.add(item);
	              } 
	          }
	       }catch (Exception e) {  
	           System.out.println("檔案上傳失敗:"+e.getMessage());
	       }
		return params;
	}
           

解釋:

1  對于整個form表單送出上來後,先是使用了封裝方法 getParamsFromMultipartRequest() 對 請求進行處理。

2  處理完資料後,添加進map中;如果包含了檔案項,則fileItemList添加一個參數;

【5】重點2:通過ImageClient來上傳圖檔即可

如果fileItemList不為空,那麼将資料流和對象名稱,用 uploadHessian() 上傳檔案。

if(this.fileItemList != null && this.fileItemList.size() > 0){
			FileItem fileItem = this.fileItemList.get(0);
			String image_key = ImageClient.uploadHessian(fileItem.getInputStream(), fileItem.getName());
			imgUrl = ImageClient.getPic(image_key, null, null, null);
		}
           

【6】重點3:ImageClient

每個公司都會使用圖檔伺服器,比如騰訊雲、阿裡雲,華為雲等等;ImageClient 其實是對第三方api進行的一個封裝;ImageClient類是個工具類,包含了調用第三方api的方法。

舉個例子(阿裡雲):

/**
	 * 上傳圖檔  傳回圖檔key
	 * @param is
	 * @param fileName
	 * @return
	 */
	public static String uploadHessian(InputStream is,String fileName) {
		return AliImageClient.uploadHessian(is, fileName);
	}
	
           

【7】重點4:再往下就是阿裡雲的第三方api,這裡涉及到敏感資訊,便不再叙述;隻要了解到一點,我們使用的是别人提供的服務,這種服務是非常難搞的(是以一般隻有巨頭有實力提供這種服務),圖檔伺服器接口由第三方提供,通過上傳資料流擷取到key值,然後用api拿到存儲在伺服器(雲端)的圖檔url。這個過程要了解。