国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android程序開(kāi)發(fā)通過(guò)HttpURLConnection上傳文件到服務(wù)器

2020-04-11 10:54:41
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

 一:實(shí)現(xiàn)原理

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

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

服務(wù)器端HTTP API, 我是基于Spring3 MVC實(shí)現(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實(shí)現(xiàn)上傳的代碼,我把它封裝成一個(gè)單獨(dú)的類文件,這樣大家可以直接使用,只要傳入上傳的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)過(guò)本人測(cè)試,效果杠杠的!!所以請(qǐng)忘記HttpClient這個(gè)東西,android開(kāi)發(fā)再也不需要它了。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 清丰县| 原平市| 苏尼特右旗| 云安县| 余干县| 千阳县| 崇明县| 钟祥市| 南岸区| 建湖县| 吉首市| 高要市| 麻城市| 三门县| 仪陇县| 宿松县| 固安县| 富源县| 金溪县| 龙胜| 南阳市| 伊宁县| 石河子市| 大关县| 马关县| 略阳县| 东辽县| 仙游县| 竹溪县| 荔波县| 景洪市| 河池市| 潼南县| 邛崃市| 公安县| 高阳县| 绥江县| 元朗区| 石狮市| 贵阳市| 柘城县|