java文件上傳


文件上傳

1.1文件上傳概述

​ 就是將客戶端的數據發送到服務器上的操作

1.2文件上傳要求
1.2.1瀏覽器端要求(通用瀏覽器的要求)
  • 表單提交方式 post

  • 提供文件上傳框(組件) input type="file"

  • 表單的entype屬性必須為 multipart/form-data

1.2.2服務器端要求

​ 要使用request.getInputStream()來獲取數據.

注意:

​ 若表單使用了 multipart/form-data ,使用原生request.getParameter()去獲取參數的時候都為null

1.3常見的文件上傳框架

​ commons-fileupload

​ struts2(底層:commons-fileupload)

​ serlvet3.0

​ ...

1.4commons-fileupload的使用

​ apache出品的一款專門處理文件上傳的工具類

​ 使用步驟:

  1. 導入jar包

  2. 創建磁盤文件項工廠

              DiskFileItemFactory factory=new DiskFileItemFactory();
  3. 創建核心上傳對象


             ServletFileUpload upload=new ServletFileUpload(factory);
  4. 解析請求,獲取所有的上傳組件 List<FileItem>


              List<FileItem> list=upload.parseRequest(request);
  5. 遍歷list 獲取每一個上傳項

FileItem的API:

​ getFiledName():獲取標簽里面name屬性的值

​ isFormFiled():判斷是否是普通上傳組件;

​ true:普通上傳組件,不是File text,password,hidden....

​ false:文件上傳組件 是File <input type="file">

  • 普通上傳組件, 不是File

    getString("utf-8"):獲取(普通上傳組件)用戶輸入的內容

  • 文件上傳組件 是File

    getName():獲取文件名稱

    getInputStream():獲取文件的流(文件內容)

    delete():刪除文件上傳時候產生的臨時文件

Eg:

 
        
 1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2         
 3         try {
 4             //創建磁盤文件項工廠
 5             DiskFileItemFactory factory = new DiskFileItemFactory();
 6             //創建核心上傳對象
 7             ServletFileUpload fileUpload = new ServletFileUpload(factory);
 8             //獲得所有的上傳組件
 9             List<FileItem> list = fileUpload.parseRequest(request);
10             for (FileItem fileItem : list) {
11                 //獲得標簽的name屬性值
12                 System.out.println(fileItem.getFieldName());
13                 //判斷是否是文件上傳
14                 if(fileItem.isFormField()){
15                     //普通上傳組件
16                     //獲得普通上傳組件的內容
17                     System.out.println(fileItem.getString("utf-8"));
18                     
19                 }else{
20                     //文件上傳組件
21                     //獲得文件上傳組件的輸入流
22                     InputStream is = fileItem.getInputStream();
23                     
24                     //創建文件輸出流
25                     OutputStream os= new FileOutputStream("G:/1.txt");
26                     
27                     IOUtils.copy(is, os);
28                     
29                     os.close();
30                 }
31                 
32             }
33             
34         } catch (Exception e) {
35             e.printStackTrace();
36         }
37     }

 

 

1.5上傳注意問題
  1. 文件重名問題

    給文件取一個隨機名稱, uuid方式 或者 毫秒值++三個隨機數

  2. 文件名稱問題 目的是獲得文件真實名字,不帶盤符的

    如果是IE:文件名帶盤符E:/data/Desktop/a.txt

    其它的火狐,谷歌是文件本來的名字: a.txt

    瀏覽器不同,有可能獲取的名稱不同(IE是帶盤符的), 1.txt 或者 G:\1.txt

    1. 常見的目錄分離

      按用戶划分

      按時間划分

      按數量划分

      隨機划分 算法:

       
                  
      1  /**
      2   * 獲取文件目錄,可以獲取256個隨機目錄
      3      * @return 隨機目錄   /a/c
      4      */
      5     public static String getDir(){
      6         String s="0123456789ABCDEF";//16個
      7         Random r = new Random();
      8         return "/"+s.charAt(r.nextInt(16))+"/"+s.charAt(r.nextInt(16));
      9     }

       

三,思路分析

  1. 在left.jsp上添加一個連接,"添加商品",點擊,在主頁面上打開一個表單頁面


      .../adminProductServlet?method=addUI
  1. 創建addUI()方法

    ​ 調用業務,獲得所有的分類List

    ​ 把List存到request,轉發到 /admin/product/add.jsp

  2. 在add.jsp頁面,點擊確定按鈕,把數據提交到服務器


    //請求的Servlet還能繼承BaseServlet??? 不可以 因為BaseServlet依賴requet.getParamet("method")獲得方法名
    <form action="${pageContext.request.contextPath}/addProductServlet" method="post" enctype="multipart/form-data">
    //把每一個表單子標簽設置name屬性
    </form>
  3. 創建AddProductServlet ,在doGet()方法里面:

    ​ //封裝成Product, 調用業務,最終保存到數據庫

    ​ //保存圖片文件到服務器

  4. 創建Service

  5. 創建Dao

 

四,代碼實現

  • WEB層(AddProductServlet)

     1 public class AddProductServlet extends HttpServlet {
     2     private static final long serialVersionUID = 1L;
     3     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     4         try {
     5             //1.創建磁盤文件項工廠
     6             DiskFileItemFactory factory = new DiskFileItemFactory();
     7             //2.創建核心上傳對象
     8             ServletFileUpload upload = new ServletFileUpload(factory);
     9             //3.解析請求,獲得文件項集合
    10             List<FileItem> list = upload.parseRequest(request);
    11             
    12             Map<String, String> map = new HashMap<String,String>();
    13             //4.遍歷文件項集合
    14             for (FileItem fileItem : list) {
    15                 //4.1獲得表單里面name的值,(name的值應該和javaBean的屬性是一致)
    16                 String fieldName = fileItem.getFieldName();
    17                 //4.2 判斷是否是file
    18                 if(fileItem.isFormField()){
    19                     //不是file
    20                     //a.獲得value的值
    21                     String value = fileItem.getString("utf-8");
    22                     map.put(fieldName, value);
    23                     
    24                 }else{
    25                     //是file
    26                     //a.獲得文件名
    27                     String fileName = fileItem.getName();
    28                     //b.獲得真實的文件名 
    29                     fileName = UploadUtils.getRealName(fileName);
    30                     //c.獲得隨機文件名
    31                     String uuidName = UploadUtils.getUUIDName(fileName);
    32                     //d.獲得一個隨機目錄名 /a/b/c
    33                     String dir = UploadUtils.getDir();
    34                     //e.存到map里面  products/1/c_0001.jpg
    35                     map.put(fieldName, "products"+dir+"/"+uuidName);
    36                     //f:把文件保存在服務器 
    37                     String realPath = getServletContext().getRealPath("/products");
    38                     File fileDir = new File(realPath, dir);
    39                     if(!fileDir.exists()){
    40                         fileDir.mkdirs();
    41                     }
    42                     
    43                     OutputStream os =  new FileOutputStream(new File(fileDir, uuidName));
    44                     //獲得輸入流
    45                     InputStream is = fileItem.getInputStream();
    46                     IOUtils.copy(is, os);
    47                     //刪除臨時文件
    48                     fileItem.delete();
    49                     //關閉流
    50                     IOUtils.closeQuietly(is);
    51                     IOUtils.closeQuietly(os);
    52                 }
    53             }
    54             
    55             //5.封裝product對象
    56             Product product = new Product();
    57             //5.1 使用beanutils封裝
    58             BeanUtils.populate(product, map);
    59             //5.2手動封裝pid,pdate,pflag
    60             product.setPid(UUIDUtils.getId());
    61             product.setPdate(new Date());
    62             product.setPflag(Constant.PRODUCT_IS_UP);
    63             //5.3手動設置 category
    64 Category c = new Category();
    65 c.setCid((String)map.get("cid"));
    66 product.setCategory(c);
    67 
    68 ProductService productService = (ProductService) BeanFactory.getBean("ProductService");
    69 System.out.println(product.toString());
    70 
    71 productService.save(product);
    72 
    73 response.sendRedirect(request.getContextPath()+"/adminProductServlet?method=findAll");
    74 
    75     } catch (Exception e) {
    76 e.printStackTrace();
    77     }
    78     }
    79 80 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    81 doGet(request, response);
    82     }
    83 84 }

     

 

快捷鍵:

  • 快速查找頁面或者Java類

 

 

 

  • 查看繼承關系

  • 查看當前類的結構(方法)

 

 

封裝:

  • WEB(Servlet): 表單里面/前端頁面獲得數據比較多,通常在WEB層封裝,傳給Service

  • Dao: 是從數據庫獲得, 通過只封裝和數據庫語句對應的數據(JavaBean,List), 傳給Service

  • Service: 補充WEB層傳過來的,傳給Dao; 補充Dao 傳過來的,傳給WEB (eg:PageBean)

  • JavaBean: 如果當前javaBean需要封裝邏輯,定義方法; 通常的話是一張表對應一個JavaBean

---恢復內容結束---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM