中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Android端通過HttpURLConnection上傳文件到服務器

2018-07-20    來源:open-open

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

Android端通過HttpURLConnection上傳文件到服務器

一:實現(xiàn)原理

最近在做Android客戶端的應用開發(fā),涉及到要把圖片上傳到后臺服務器中,自己選擇了做Spring3 MVC HTTP API作為后臺上傳接口,android客戶端我選擇用HttpURLConnection來通過form提交文件數(shù)據(jù)實現(xiàn)上傳功能,本來想網(wǎng)上搜搜拷貝一下改改代碼就好啦,發(fā)現(xiàn)根本沒有現(xiàn)成的例子,多數(shù)的例子都是基于HttpClient的或者是基于Base64編碼以后作為字符串來傳輸圖像數(shù)據(jù),于是我不得不自己動手,參考了網(wǎng)上一些資料,最終實現(xiàn)基于HttpURLConnection上傳文件的android客戶端代碼,廢話少說,其實基于HttpURLConnection實現(xiàn)文件上傳最關(guān)鍵的在于要熟悉Http協(xié)議相關(guān)知識,知道MIME文件塊在Http協(xié)議中的格式表示,基本的傳輸數(shù)據(jù)格式如下:


其中boundary表示form的邊界,只要按照格式把內(nèi)容字節(jié)數(shù)寫到HttpURLConnection的對象輸出流中,服務器端的Spring Controller 就會自動響應接受,跟從瀏覽器頁面上上傳文件是一樣的。

服務器端HTTP API, 我是基于Spring3 MVC實現(xiàn)的Controller,代碼如下:
@RequestMapping(value = "/uploadMyImage/{token}", method = RequestMethod.POST)
public @ResponseBody String getUploadFile(HttpServletRequest request, HttpServletResponse response,
		@PathVariable String token) {
	logger.info("spring3 MVC upload file with Multipart form");
	logger.info("servlet context path : " + request.getSession().getServletContext().getRealPath("/"));
	UserDto profileDto = userService.getUserByToken(token);
	String imgUUID = "";
	try {
		if (request instanceof MultipartHttpServletRequest && profileDto.getToken() != null) {
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			logger.info("spring3 MVC upload file with Multipart form");
			// does not work, oh my god!!
			MultipartFile file = multipartRequest.getFiles("myfile").get(0);
			InputStream input = file.getInputStream();
			long fileSize = file.getSize();
			BufferedImage image = ImageIO.read(input);
			// create data transfer object
			ImageDto dto = new ImageDto();
			dto.setCreateDate(new Date());
			dto.setFileName(file.getOriginalFilename());
			dto.setImage(image);
			dto.setCreator(profileDto.getUserName());
			dto.setFileSize(fileSize);
			dto.setType(ImageAttachmentType.CLIENT_TYPE.getTitle());
			dto.setUuid(UUID.randomUUID().toString());

			/// save to DB
			imgUUID = imageService.createImage(dto);
			input.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
		logger.error("upload image error", e);
	}

	return imgUUID;
}

Android客戶端基于HttpURLConnection實現(xiàn)上傳的代碼,我把它封裝成一個單獨的類文件,這樣大家可以直接使用,只要傳入上傳的URL等參數(shù)即可。代碼如下:

package com.demo.http;

import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Random;

import android.os.Handler;
import android.util.Base64;
import android.util.Log;

public class UploadImageTask implements APIURLConstants {
	private String requestURL = DOMAIN_ADDRESS + UPLOAD_DESIGN_IMAGE_URL; // default
	private final String CRLF = "\r\n";
	private Handler handler;
	private String token;
	public UploadImageTask(String token, Handler handler) {
		this.handler = handler;
		this.token = token;
	}

	public String execute(File...files) {
		InputStream inputStream = null;
		HttpURLConnection urlConnection = null;
		FileInputStream fileInput = null;
		DataOutputStream requestStream = null;
		handler.sendEmptyMessage(50);
		try {
			// open connection
			URL url = new URL(requestURL.replace("{token}", this.token));
			urlConnection = (HttpURLConnection) url.openConnection();
			// create random boundary
			Random random = new Random();
			byte[] randomBytes = new byte[16];
			random.nextBytes(randomBytes);
			String boundary = Base64.encodeToString(randomBytes, Base64.NO_WRAP);

			/* for POST request */
			urlConnection.setDoOutput(true);
			urlConnection.setDoInput(true);
			urlConnection.setUseCaches(false);
			urlConnection.setRequestMethod("POST");
			long size = (files[0].length() / 1024);
			if(size >= 1000) {
				handler.sendEmptyMessage(-150);
				return "error";
			}
			// 構(gòu)建Entity form
			urlConnection.setRequestProperty("Connection", "Keep-Alive");
			urlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
			urlConnection.setRequestProperty("Cache-Control", "no-cache");
			
			// never try to chunked mode, you need to set a lot of things
			//	if(size > 400) {
			//		urlConnection.setChunkedStreamingMode(0);
			//	}
			//	else {
			//		urlConnection.setFixedLengthStreamingMode((int)files[0].length());
			//	}
			// end comment by zhigang on 2016-01-19
			
			/* upload file stream */
			fileInput = new FileInputStream(files[0]);
			requestStream = new DataOutputStream(urlConnection.getOutputStream());
			String nikeName = "myfile";
			requestStream = new DataOutputStream(urlConnection.getOutputStream());
			requestStream.writeBytes("--" + boundary + CRLF);
			requestStream.writeBytes("Content-Disposition: form-data; name=\"" + nikeName + "\"; filename=\"" + files[0].getName() + "\""+ CRLF);
			requestStream.writeBytes("Content-Type: " + getMIMEType(files[0]) + CRLF);
			requestStream.writeBytes(CRLF);
			// 寫圖像字節(jié)內(nèi)容
			int bytesRead;
			byte[] buffer = new byte[8192];
			handler.sendEmptyMessage(50);
			while((bytesRead = fileInput.read(buffer)) != -1) {
				requestStream.write(buffer, 0, bytesRead);
			}
			requestStream.flush();
			requestStream.writeBytes(CRLF);
			requestStream.flush();
			requestStream.writeBytes("--" + boundary + "--" + CRLF);
			requestStream.flush();
			fileInput.close();

			// try to get response
			int statusCode = urlConnection.getResponseCode();
			if (statusCode == 200) {
				inputStream = new BufferedInputStream(urlConnection.getInputStream());
				String imageuuId = HttpUtil.convertInputStreamToString(inputStream);
				Log.i("image-uuid", "uploaded image uuid : " + imageuuId);
				handler.sendEmptyMessage(50);
				return imageuuId;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(requestStream != null) {
				try {
					requestStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fileInput != null) {
				try {
					fileInput.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (urlConnection != null) {
				urlConnection.disconnect();
			}
		}
		handler.sendEmptyMessage(50);
		return null;
	}

	private String getMIMEType(File file) {
		String fileName = file.getName();
		if(fileName.endsWith("png") || fileName.endsWith("PNG")) {
			return "image/png";
		}
		else {
			return "image/jpg";
		}
	}

}
經(jīng)過本人測試,效果杠杠的。∷哉埻汬ttpClient這個東西,android開發(fā)再也不需要它了。


標簽: isp 代碼 服務器 服務器端

版權(quán)申明:本站文章部分自網(wǎng)絡,如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:sphinx 增量索引實現(xiàn)實例

下一篇:Java操作Hbase進行建表、刪表以及對數(shù)據(jù)進行增刪改查,條件查詢