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