web專案之檔案上傳
阿新 • • 發佈:2019-01-03
分析
1.上傳條件(3個):
1.1 表單的請求方式必須是 post
1.2 表單提交的型別 enctype=”multipart/form-data”
1.3 上傳控制元件 file型別 必須得寫name屬性:
<input type="file" name="filename"/>
2.處理上傳:第三方庫
2.1 新增jar(2個) commons-fileupload-xx.jar commons-io-xx.jar 2.2 上傳步驟程式碼: 2.2.1 建立配置類 DiskFileItemFactory a.配置臨時目錄new File(); b.配置臨時目錄大小,預設10KB, C:\User\Administer\AppData\Local\Temp\ 2.2.2 建立上傳的核心類ServletFileUpload 常用:setProgressListener();設定進度 引數1:當前上傳的位元組數 引數2:總的位元組數 2.2.3 解析請求 parseRequest(request); 返回值List<FileItem> 2.2.4 遍歷取出每一項FileItem 2.2.5 判斷型別 isFormFiled() 成立,普通表單: fileItem.getFiledName(); fileItem.getString("utf-8"); 不成立,上傳項 :fileItem.write();
3.上傳的注意事項:
3.1 檔名的獲取: fileItem.getName(); 不同瀏覽器取到的結果不一樣。 字串擷取 3.2 放置檔名重複覆蓋內容: 處理檔名(唯一) System.currentMillons()+filename; UUID.randomUUID()+“_”+filename; 3.3 打散目錄: 3.3.1 直接在跟目錄下儲存 //建立目錄 File file=new File(“C:\\img”); if(!file.exists()){ file.mkDirs(); } //建立檔案 File file2=new File(file,filename) 3.3.2 按照日期打散目錄 long time = System.currentMillons; SimpleDateFomat format =new SimpleDateFomat("yyyy-MM-dd"); String date = format.format(new Date(time)); //建立目錄 File file=new File(“C:\\img”,date); if(!file.exists()){ file.mkDirs(); } //建立檔案 File file2=new File(file,filename); 3.3.3 按照hashcode值打散目錄 int code= filename.hashCode; String code1 = Integer.toHexString(code); String dir = code1.charAt(0)+"\\"+code1.charAt(1); //建立目錄 File file=new File(“C:\\img”,dir); if(!file.exists()){ file.mkDirs(); } //建立檔案 File file2=new File(file,filename)
4.上傳功能及圖片展示:
add.jsp AddShopServlet 處理的資料型別: Map<String,String> key:表單項的name value:表單項的值 展示:網路地址: tomcat的虛擬目錄: server.xml中Host下新增如下話語:(配置當前使用tomcat) conf/server.xml backup/server.xml Eclipse: servers/server.xml docBase:磁碟的真實目錄(該目錄必須是存在) path:虛擬目錄(對映在tomca伺服器上的地址) <Context path="/img01" docBase="c:\img"></Context> 訪問的路徑是:http://localhost:8080/img01/具體資源
程式碼實現:
FileUtils.java:
package com.qf.utils;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import org.apache.commons.fileupload.FileItem;
public class FileUtils {
/**
*
* @param diskPath磁碟路徑
* @return 網路訪問路徑
*
*/
public static String getNetPath(String diskPath) {
int index1 = diskPath.indexOf("img");
String basePath= "http://localhost:8080/img01/"+diskPath.substring(index1+4).replace("\\", "/") ;
System.out.println(basePath);
return basePath;
}
// 獲取上傳的檔名稱
public static String getFileName(FileItem fileItem) {
// 在不同瀏覽器取值結果不一樣(name有的是隻有名稱,有的是連帶的路徑的名稱)
String name = fileItem.getName();
System.out.println("name" + name);
String filename = name.substring(name.lastIndexOf("\\") + 1);
System.out.println("filename= " + filename);
return filename;
}
//保證檔名稱唯一性
public static String getFileNameByHashCode(FileItem fileItem) {
String filename = getFileName(fileItem);
// 方式一:使用時間戳區分:
// filename =System.currentTimeMillis()+filename;
// 方式二: 使用UUID區分:
filename = UUID.randomUUID() + "_" + filename;
return filename;
}
// 方式一:預設
/**
* @param fileItem
* 上傳項
* @return 返回的是上傳要寫入的檔案目錄
*/
public static File test1(FileItem fileItem) {
File file = new File("C:\\img");
if (!file.exists()) {
// mkdirs:建立多級目錄,即使父目錄不存在也能建立成功
// mkdir:只能單級目錄,而且要求是必須父目錄存在
file.mkdirs();
}
// 建立檔案
File file2 = new File(file, getFileNameByHashCode(fileItem));
return file2;
}
// 方式二:保證名稱的唯一性
public static File test2(FileItem fileItem) {
File file = new File("C:\\img");
if (!file.exists()) {
// mkdirs:建立多級目錄,即使父目錄不存在也能建立成功
// mkdir:只能單級目錄,而且要求是必須父目錄存在
file.mkdirs();
}
// 建立檔案
File file2 = new File(file, getFileNameByHashCode(fileItem));
return file2;
}
// 方式三:檔案目錄進行變化
// 1.按照日期儲存(按照日期打散檔案)
public static File test3(FileItem fileItem) {
long time = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String date = format.format(new Date(time));
System.out.println("date" + date);
// 目錄
File file = new File("C:\\img", date);
if (!file.exists()) {
// mkdirs:建立多級目錄,即使父目錄不存在也能建立成功
// mkdir:只能單級目錄,而且要求是必須父目錄存在
file.mkdirs();
}
// 建立檔案
File file2 = new File(file, getFileNameByHashCode(fileItem));
return file2;
}
// 2.按照hashcode隨機值儲存(按照hashcode打散檔案)
public static File test4(FileItem fileItem) {
String filename =getFileNameByHashCode(fileItem);
// 獲取檔名稱hashcode值
int code = filename.hashCode();
System.out.println("==code=" + code);
// 把int型別的值轉化成16進位制的字串
String code1 = Integer.toHexString(code);
System.out.println("==code1=" + code1);
String dir = code1.charAt(0) + "\\" + code1.charAt(1);
// 目錄
File file = new File("C:\\img", dir);
if (!file.exists()) {
// mkdirs:建立多級目錄,即使父目錄不存在也能建立成功
// mkdir:只能單級目錄,而且要求是必須父目錄存在
file.mkdirs();
}
// 建立檔案
File file2 = new File(file, filename);
return file2;
}
}
UploadUtils.java:
package com.qf.utils;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadUtils {
public static Map<String, String> getRequestData(HttpServletRequest request) {
Map<String, String> map = new HashMap();
if (!ServletFileUpload.isMultipartContent(request)) {
return null;
}
// 1.配置DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File("c:\\"));
// 2.建立上傳核心類
ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
// 3.解析請求
try {
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
for (FileItem fileItem : fileItems) {
// 判斷表單型別
if (fileItem.isFormField()) {
// 普通表單
String name = fileItem.getFieldName();
String value = fileItem.getString("utf-8");
map.put(name, value);
} else {
// 上傳項
File file = FileUtils.test4(fileItem);
String netPath = FileUtils.getNetPath(file.getAbsolutePath());
System.out.println("netPath=" + netPath);
map.put("imgurl", netPath);
fileItem.write(file);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
}
AddShopServlet.java:
package com.qf.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import com.mysql.jdbc.UpdatableResultSet;
import com.qf.domain.Shop;
import com.qf.service.ShopService;
import com.qf.service.impl.ShopServiceImpl;
import com.qf.utils.UploadUtils;
public class AddShopServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map<String, String> map = UploadUtils.getRequestData(request);
Shop shop = new Shop();
try {
BeanUtils .populate(shop, map);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(shop.getName());
shop.setId(UUID.randomUUID().toString());
ShopService ss = new ShopServiceImpl();
try {
ss.addProducts(shop);
//新增成功
//新增完資料 應該走查詢servlet
request.getRequestDispatcher("queryAllShopListServlet").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
//新增失敗的話 返回到新增頁面
request.getRequestDispatcher("admin/products/add.jsp").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
修改三個地方的server.xml
地方
1.eclipse的server.xml
2.tomcat下的conf目錄的server.xml
3.tomcat下的backup目錄的server.xml(有的可能沒有,沒有就配前兩個就行)
如何配?
修改server.xml 加上這句話:
<Context path="/img01" docBase="c:\img"></Context>