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

【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。這個過程要了解。