上传图片或者说上传文件,几乎每个应用里,或多或少都有,比如修改头像,修改形象照等,也许,目前出现了很多封装的框架,可以很简单的来实现,比如OkHttp,Retrofit等,那么用HttpURLConnection这个最基本的请求,如何实现上传一张图片呢?
无论用哪个进行上传,首先分析下,把一张图片或者文件,上传到服务端,需要什么条件?
1、接口肯定得有(当然这个是废话,没有接口,怎么和服务端连接)
2、图片资源(这个也是废话,没有图片,还上传个锤子)
3、参数(包含图片的参数,头参等)
基本上有了上述三个条件,我们就可以愉快的进行上传了。
接口
以下是随便找的一个测试接口。
图片资源
第一个条件接口有了,图片我们可以选取拍照或者相册中的,这里为了测试简单,我在模拟器sd卡里放了一张图片,就用这张图片进行上传。
参数
前两个条件都有了,最主要的就是看第三个条件了,参数,接口文档中已经给出了,两个头参,userId和sessionId,这是用户的标识,因为这是一个修改头像,肯定需要用户的标识,没有标识,谁知道你要给谁修改头像,还有一个入参image,这个是图片的参数,也就是,你要上传的图片,看清楚是file类型;除了文档中给的这些参数,我们还需要哪些参数呢?哎,这就需要我们进一步分析了。
我们先用接口测试工具,对这个接口进行测试,打开ApiPost或者PostMan,对上面的接口,进行请求。
入参这,记得也要选
我们通过测试,可以发现,图片已经上传成功,那么这个接口呢,是可行的,但是往服务端传递的时候,参数我们怎么查看呢?如果大家有抓包工具的话,相对来说就简单了很多,打开你的抓包工具Charles或者Fiddler,就可以很清楚的看到了,比如下面是我抓到的。
找到接口,右边上半部分,就是我们发起请求后,客户端做的动作,也就是,携带了哪些参数,我们一个点击,就执行了这么多的参数携带,我们可以继续分析,哪些参数是最重要的,是必须要携带的呢?
你会发现有几个是比较熟悉的,哪些呢,就是sessionId和userId,这是接口文档中的头参,还有image入参,当然了,我们不得不去分析下,别的参数,比如Content-Type,请求中的媒体类型信息,这个一定得带的,以及后面的分隔符,可以发现箭头,我指了两处,都是需要传的,还有连接符--,以及空行,以及结尾处,如下图。
也就是说,我用红色箭头或者方框圈住的部分,是我们必须需要的参数,这是我们通过抓包工具,查看到的,那么,在代码里盖如何表现呢?这个就很简单了,参数我们都有了,直接用代码传递就可以了。
代码
下面我写一个方法,传递接口和图片地址,全部代码如下:
privatestaticfinalStringnextLine="\r\n"; privatestaticfinalStringtwoHyphens="--";//连接符//分割线 随便写一个privatestaticfinalStringboundary="android"; privatevoidupLoadFile(finalStringurl, finalStringfilePath) { newThread() { publicvoidrun() { super.run(); Filefile=newFile(filePath); HttpURLConnectionconnection=null; try { URLurl1=newURL(url); connection= (HttpURLConnection) url1.openConnection(); connection.setDoOutput(true);//允许输出流//设置请求参数格式以及boundary分割线connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary); //传递头参connection.setRequestProperty("userId", "1892"); connection.setRequestProperty("sessionId","15856368900771892"); OutputStreamoutputStream=newDataOutputStream(connection.getOutputStream()); //分隔符头部Stringheader=twoHyphens+boundary+nextLine; //分隔符参数设置header+="Content-Disposition: form-data;name=\"image\";"+"filename=\""+file.getName() +"\""+nextLine+nextLine; //写入输出流outputStream.write(header.getBytes()); //读取文件并写入FileInputStreaminputStream=newFileInputStream(file); byte[] bytes=newbyte[1024]; intlength; while ((length=inputStream.read(bytes)) !=-1) { outputStream.write(bytes, 0, length); } //文件写入完成后加回车outputStream.write(nextLine.getBytes()); //写入结束分隔符Stringfooter=nextLine+twoHyphens+boundary+twoHyphens+nextLine; outputStream.write(footer.getBytes()); outputStream.flush(); if (connection.getResponseCode() ==200) { InputStreaminputStream1=connection.getInputStream(); Stringjson=newString(ByteStreams.toByteArray(inputStream1)); Log.i("====", json); } } catch (MalformedURLExceptione) { e.printStackTrace(); } catch (IOExceptione) { e.printStackTrace(); } } }.start(); }