關於Java後臺處理android上傳圖片的問題

最近一直被一個問題困擾,就是android上傳圖片到服務器,但是最終都沒能獲得圖片,不知道是什麼原因,先曬出後臺代碼(該代碼也是參考網上大多數網友的寫法)

主要用到兩個jar包,分別是commons-io 以及commons-fileupload,網上可以下載的到


package servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadHandleServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 得到上傳文件的保存目錄
        String savePath = this.getServletContext().getRealPath(
                "upload");

        // 上傳時生成的臨時文件保存目錄
        String tempPath = this.getServletContext().getRealPath("temp");
        System.out.println(tempPath);
        File tmpFile = new File(tempPath);

        // 判斷上傳文件的保存目錄是否存在
        if (!tmpFile.exists()) {
            // 創建臨時目錄
            tmpFile.mkdir();
        }
        // 消息提示
        String message = "";
        try {
            // 使用Apache文件上傳組件處理文件上傳步驟:
            // 1、創建一個DiskFileItemFactory工廠
            DiskFileItemFactory factory = new DiskFileItemFactory();

         
            // 設置上傳時生成的臨時文件的保存目錄
            factory.setRepository(tmpFile);

            // 2、創建一個文件上傳解析器
            ServletFileUpload upload = new ServletFileUpload(factory);

     //此處是爲了監聽上傳文件的進度,可有可無

            upload.setProgressListener(new ProgressListener() {
                public void update(long pBytesRead, long pContentLength,
                        int arg2) {
                    System.out.println("文件大小爲:" + pContentLength + ",當前已處理:"
                            + pBytesRead);

                }
            });

            // 解決上傳文件名的中文亂碼
            upload.setHeaderEncoding("UTF-8");
            // 3、判斷提交上來的數據是否是上傳表單的數據
            if (!ServletFileUpload.isMultipartContent(request)) {
                // 按照傳統方式獲取數據
                return;
            }
            
             upload.setFileSizeMax(1024*1024);
             upload.setSizeMax(1024*1024*10);
            
            
            
            // 4、使用ServletFileUpload解析器解析上傳數據
            List<FileItem> list = upload.parseRequest(request);

      //此處出現的問題好多







            for (FileItem item : list) {
                // 如果fileitem中封裝的是普通輸入項的數據
                if (item.isFormField()) {
                    String name = item.getFieldName();
                    // 解決普通輸入項的數據的中文亂碼問題
                    String value = item.getString("UTF-8");
                    // value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + "=" + value);
                } else {// 如果fileitem中封裝的是上傳文件
                    // 得到上傳的文件名稱,
                    String filename = item.getName();
                    System.out.println(filename);
                    if (filename == null || filename.trim().equals("")) {
                        continue;
                    }
                    // 注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如:
                    // c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
                    // 處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
                    filename = filename
                            .substring(filename.lastIndexOf("\\") + 1);
                    // 獲取item中的上傳文件的輸入流
                    InputStream in = item.getInputStream();
                    // 創建一個文件輸出流
                    FileOutputStream out = new FileOutputStream(savePath + "\\"
                            + filename);
            
                    byte buffer[] = new byte[1024];
                    // 判斷輸入流中的數據是否已經讀完的標識
                    int len = 0;
                
                    while ((len = in.read(buffer)) > 0) {
                        // 使用FileOutputStream輸出流將緩衝區的數據寫入到指定的目錄(savePath + "\\"
                        // + filename)當中
                        out.write(buffer, 0, len);
                    }
                    // 關閉輸入流
                    in.close();
                    // 關閉輸出流
                    out.close();
                    // 刪除處理文件上傳時生成的臨時文件
                    item.delete();
                    message = "文件上傳成功!";
                }
            }
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "單個文件超出最大值!!!");
            request.getRequestDispatcher("/pages/message.jsp").forward(request,
                    response);
            return;
        } catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "上傳文件的總的大小超出限制的最大值!!!");
            request.getRequestDispatcher("/message.jsp").forward(request,
                    response);
            return;
        } catch (Exception e) {
            message = "文件上傳失敗!";
            e.printStackTrace();

        }
        request.setAttribute("message", message);
        request.getRequestDispatcher("/pages/message.jsp").forward(request,
                response);
    }

    
    private String makePath(String filename,String savePath){
       
                 int hashcode = filename.hashCode();
                 int dir1 = hashcode&0xf;  //0--15
                 int dir2 = (hashcode&0xf0)>>4;  //0-15
                 //構造新的保存目錄
                 String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
                 //File既可以代表文件也可以代表目錄
                 File file = new File(dir);
                //如果目錄不存在
                 if(!file.exists()){
                     //創建目錄
               file.mkdirs();
                 }
                 return dir;
             }
    
     private String makeFileName(String filename){  //2.jpg
             
                  return UUID.randomUUID().toString() + "_" + filename;
              }
    
    
    
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }
}

 List<FileItem> list = upload.parseRequest(request) 爲什麼獲得list集合爲空,參考網上意見,是因爲Struts本身自帶過濾,如下:

修改前:

<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

修改後:

<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>

但是我沒有用到struts,僅僅只是用了servlet,所以對我不適用,還是縣曬出我的web.xml裏面的配置:

<servlet>
     <servlet-name>UploadHandleServlet</servlet-name>
    <servlet-class>servlet.UploadHandleServlet</servlet-class>
 </servlet>
 
<servlet-mapping>
    <servlet-name>UploadHandleServlet</servlet-name>
    <url-pattern>/servlet/UploadHandleServlet</url-pattern>
 </servlet-mapping> 
爲什麼獲取不到圖片呢,忘記說了,android不是我寫的,所以沒有辦法曬出前端代碼,網上的android 前端好多這麼寫的:

  1. package com.example.photo;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.DataOutputStream;  
  5. import java.io.File;  
  6. import java.io.FileInputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.io.InputStreamReader;  
  10. import java.io.OutputStream;  
  11. import java.net.HttpURLConnection;  
  12. import java.net.MalformedURLException;  
  13. import java.net.URL;  
  14. import java.util.UUID;  
  15.   
  16.   
  17. public class HttpAssist {  
  18.     private static final String TAG = "uploadFile";  
  19.     private static final int TIME_OUT = 10 * 10000000// 超時時間  
  20.     private static final String CHARSET = "utf-8"// 設置編碼  
  21.     public static final String SUCCESS = "1";  
  22.     public static final String FAILURE = "0";  
  23.   
  24.     public static String uploadFile(File file) {  
  25.         String BOUNDARY = UUID.randomUUID().toString(); // 邊界標識 隨機生成  
  26.         String PREFIX = "--", LINE_END = "\r\n";  
  27.         String CONTENT_TYPE = "multipart/form-data"// 內容類型  
  28.         String RequestURL = "http://192.168.0.100:7080/YkyPhoneService/Uploadfile1";  
  29.         try {  
  30.             URL url = new URL(RequestURL);  
  31.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  32.             conn.setReadTimeout(TIME_OUT);  
  33.             conn.setConnectTimeout(TIME_OUT);  
  34.             conn.setDoInput(true); // 允許輸入流  
  35.             conn.setDoOutput(true); // 允許輸出流  
  36.             conn.setUseCaches(false); // 不允許使用緩存  
  37.             conn.setRequestMethod("POST"); // 請求方式  
  38.             conn.setRequestProperty("Charset", CHARSET); // 設置編碼  
  39.             conn.setRequestProperty("connection""keep-alive");  
  40.             conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="  
  41.                     + BOUNDARY);  
  42.             if (file != null) {  
  43.                 /** 
  44.                  * 當文件不爲空,把文件包裝並且上傳 
  45.                  */  
  46.                 OutputStream outputSteam = conn.getOutputStream();  
  47.   
  48.                 DataOutputStream dos = new DataOutputStream(outputSteam);  
  49.                 StringBuffer sb = new StringBuffer();  
  50.                 sb.append(PREFIX);  
  51.                 sb.append(BOUNDARY);  
  52.                 sb.append(LINE_END);  
  53.                 /** 
  54.                  * 這裏重點注意: name裏面的值爲服務器端需要key 只有這個key 纔可以得到對應的文件 
  55.                  * filename是文件的名字,包含後綴名的 比如:abc.png 
  56.                  */  
  57.   
  58.                 sb.append("Content-Disposition: form-data; name=\"img\"; filename=\""  
  59.                         + file.getName() + "\"" + LINE_END);  
  60.                 sb.append("Content-Type: application/octet-stream; charset="  
  61.                         + CHARSET + LINE_END);  
  62.                 sb.append(LINE_END);  
  63.                 dos.write(sb.toString().getBytes());  
  64.                 InputStream is = new FileInputStream(file);  
  65.                 byte[] bytes = new byte[1024];  
  66.                 int len = 0;  
  67.                 while ((len = is.read(bytes)) != -1) {  
  68.                     dos.write(bytes, 0, len);  
  69.                 }  
  70.                 is.close();  
  71.                 dos.write(LINE_END.getBytes());  
  72.                 byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END)  
  73.                         .getBytes();  
  74.                 dos.write(end_data);  
  75.                 dos.flush();  
  76.                 /** 
  77.                  * 獲取響應碼 200=成功 當響應成功,獲取響應的流 
  78.                  */  
  79.                 int res = conn.getResponseCode();  
  80.                 if (res == 200) {  
  81.                     return SUCCESS;  
  82.                 }  
  83.             }  
  84.         } catch (MalformedURLException e) {  
  85.             e.printStackTrace();  
  86.         } catch (IOException e) {  
  87.             e.printStackTrace();  
  88.         }  
  89.         return FAILURE;  
  90.     }  

  sb.append("Content-Disposition: form-data; name=\"img\"; filename=\""  


                        + file.getName() + "\"" + LINE_END); 

  sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""  


                        + file.getName() + "\"" + LINE_END); 


這兩者有什麼區別,有大神知道的說一下 啊












發佈了23 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章