Android用戶端向伺服器傳遞圖片(使用Http協議)

來源:互聯網
上載者:User

標籤:

使用Http協議向伺服器傳遞圖片,那麼就要首先瞭解Http協議這個報文裡邊的資訊格式:

  web端傳遞圖片一般都是使用表單的形式來傳遞的,通過post的形式傳遞的,在這裡要使用到兩個jar包,分別是:commons-fileupload.jar和commons-io.jar這倆jar包。

下邊來說一說Http協議上傳檔案標頭檔的格式:

其實我們這種前背景互動是用的HTTP協議。而http協議預設是傳的字串。所以我們上傳檔案的話要加enctype = "multipart/form-data"這個參數來說明我們這傳的是檔案不是字串了。而我們做web開發的時候,瀏覽器是自動解析HTTP協議的。裡面傳的哪些東西我們不用管。只要記住幾個參數就行。而我們要上傳的檔案報文是儲存在請求的標頭檔裡面的。下面就是上傳檔案標頭檔的格式:

POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1 

  Accept: text/plain, */*    

  Accept-Language: zh-cn   

  Host: 192.168.24.56  

  Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2   

  User-Agent: WinHttpClient

  Content-Length: 3693

  Connection: Keep-Alive

  -------------------------------7db372eb000e2

  Content-Disposition: form-data; name="file"; filename="kn.jpg"

  Content-Type: image/jpeg

  (此處省略jpeg檔案位元據...)

  -------------------------------7db372eb000e2--

 

這就是Http上傳發送的檔案格式。而我們要發送的時候必然要遵循這種格式來並且不能出一點差錯包括每行後面的斷行符號,下面一段文字是網上找的感覺寫的比較精彩。(尊重原創:http://topmanopensource.iteye.com/blog/1605238)

紅色字型部分就是協議的頭。給伺服器上傳資料時,並非協議頭每個欄位都得說明,其中,content-type是必須的,它包括一個類似標誌性質的名為boundary的標誌,它可以是隨便輸入的字串。對後面的具體內容也是必須的。它用來分辨一段內容的開始。Content-Length: 3693 ,這裡的3693是要上傳檔案的總長度。綠色字型部分就是需要上傳的資料,可以是文本,也可以是圖片等。資料內容前面需要有Content-Disposition, Content-Type以及Content-Transfer-Encoding等說明欄位。最後的紫色部分就是協議的結尾了。
  注意這一行:
  Content-Type: multipart/form-data; boundary=---------------------------7db372eb000e2  
  根據 rfc1867, multipart/form-data是必須的.
  ---------------------------7db372eb000e2 是分隔字元,分隔多個檔案、表單項。其中b372eb000e2 是即時產生的一個數字,用以確保整個分隔字元不會在檔案或表單項的內容中出現。Form每個部分用分隔字元分割,分隔字元之前必須加上"--"著兩個字元(即--{boundary})才能被http協議認為是Form的分隔字元,表示結束的話用在正確的分隔字元後面添加"--"表示結束。
  前面的 ---------------------------7d 是 IE 特有的標誌,Mozila 為---------------------------71.

  只要把這些Http協議的頭部的格式梳理清楚,然後再把圖片向伺服器傳遞:直接上代碼:

 

//用戶端代碼
public class HttpPost {/** * 通過拼接的方式構造請求內容,實現參數傳輸以及檔案傳輸 * * @param acti * .nUrl * @param params * @param files * @return * @throws IOException */public static String post(String actionUrl, Map<String, String> params, Map<String, File> files) throws IOException {String BOUNDARY = java.util.UUID.randomUUID().toString();String PREFIX = "--", LINEND = "\r\n";String MULTIPART_FROM_DATA = "multipart/form-data";String CHARSET = "UTF-8";URL uri = new URL(actionUrl);HttpURLConnection conn = (HttpURLConnection) uri.openConnection();conn.setReadTimeout(5 * 1000); // 緩衝的最長時間conn.setDoInput(true);// 允許輸入conn.setDoOutput(true);// 允許輸出conn.setUseCaches(false); // 不允許使用緩衝conn.setRequestMethod("POST");conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Charsert", "UTF-8");conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);// 首先組拼文本類型的參數StringBuilder sb = new StringBuilder();for (Map.Entry<String, String> entry : params.entrySet()) {sb.append(PREFIX);sb.append(BOUNDARY);sb.append(LINEND);sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);sb.append("Content-Transfer-Encoding: 8bit" + LINEND);sb.append(LINEND);sb.append(entry.getValue());sb.append(LINEND);}DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());outStream.write(sb.toString().getBytes());// 傳送檔案資料if (files != null)for (Map.Entry<String, File> file : files.entrySet()) {StringBuilder sb1 = new StringBuilder();sb1.append(PREFIX);sb1.append(BOUNDARY);sb1.append(LINEND);sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getKey() + "\"" + LINEND);sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND);sb1.append(LINEND);outStream.write(sb1.toString().getBytes());InputStream is = new FileInputStream(file.getValue());byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1) {outStream.write(buffer, 0, len);}is.close();outStream.write(LINEND.getBytes());}// 請求結束標誌byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();outStream.write(end_data);outStream.flush();// 得到響應碼int res = conn.getResponseCode();InputStream in = conn.getInputStream();if (res == 200) {int ch;StringBuilder sb2 = new StringBuilder();while ((ch = in.read()) != -1) {sb2.append((char) ch);}}outStream.close();conn.disconnect();return in.toString();}}

 

下邊是伺服器代碼:

 

public class UploadServlet extends HttpServlet {private static final long serialVersionUID = 1L;/** * Default constructor. */public UploadServlet() {// TODO Auto-generated constructor stub}/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse *      response) */protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stub}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse *      response) */public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {RequestContext req = new ServletRequestContext(request);if (FileUpload.isMultipartContent(req)) {DiskFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload fileUpload = new ServletFileUpload(factory);fileUpload.setFileSizeMax(1024 * 1024 * 1024);List items = new ArrayList();try {items = fileUpload.parseRequest(request);} catch (Exception e) {}Iterator it = items.iterator();while (it.hasNext()) {FileItem fileItem = (FileItem) it.next();if (fileItem.isFormField()) {System.out.println(fileItem.getFieldName()+ " "+ fileItem.getName()+ " "+ new String(fileItem.getString().getBytes("ISO-8859-1"), "GBK"));} else {System.out.println(fileItem.getFieldName() + " "+ fileItem.getName() + " " + fileItem.isInMemory()+ " " + fileItem.getContentType() + " "+ fileItem.getSize());if (fileItem.getName() != null && fileItem.getSize() != 0) {File fullFile = new File(fileItem.getName());File newFile = new File("F:\\upload\\"+ fullFile.getName());try {fileItem.write(newFile);} catch (Exception E) {}} else {System.out.println("no file choosen or empty file");}}}}}}

 

Android用戶端向伺服器傳遞圖片(使用Http協議)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.