android 使用OkHttp上传多张图片

本文详细介绍了为何选择OkHttp作为多图片上传的首选框架,相较于Xutils和KJFramework,OkHttp在处理图片上传时提供了更灵活的解决方案。通过简化参数管理和优化后台接收逻辑,提高了图片上传的效率和扩展性。同时,展示了核心代码实现和SpringMvc上传图片的核心逻辑,为开发者提供了一套高效、灵活的图片上传方案。

   简述

还是先来说说为啥用OkHttp作为多图片上传的框架,原因有两点:
1、OkHttp可以作为Volley底层传输协议,速度更快
2、使用Xutils和KJFramework上传图片存在一个小问题,首先,可以上传,并且可以上传多张图片,也可以上传其他的参数,那问题在哪里呢?在后台接受参数时很不灵活,Xutlis及KJFramework使用HashMap来上传每个参数,每一张图片也必须有一个唯一的key,上传一张图片就要定义一个参数来接收,上传两张图片就要定义两个参数来接收,当上传的图片数量不确定的时候,如最多9张或者16张,后台接受图片的时候就要定义9个或者16个,这样的方式很不利于扩展,最好是一个参数接收所有所有图片,不会因为这种不确定的问题,就去定义很多的参数,然后一个个判断是否存在。OkHttp底层则不是这样,大概的浏览了下源码,底层接收参数的时候使用的是List,只要使用相同的key就可以添加到同一个list,而后台只需要根据这一个key不断遍历就行,无论多少张图片都无障碍,也没有了后顾之忧。

核心代码实现

<code class="hljs cs has-numbering"><span class="hljs-comment">//参数类型</span>
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> final MediaType MEDIA_TYPE_PNG = MediaType.parse(<span class="hljs-string">"image/png"</span>);
<span class="hljs-comment">//创建OkHttpClient实例</span>
<span class="hljs-keyword">private</span> final OkHttpClient client = <span class="hljs-keyword">new</span> OkHttpClient();

MultipartBuilder builder = <span class="hljs-keyword">new</span> MultipartBuilder().type(MultipartBuilder.FORM);

<span class="hljs-comment">//遍历map中所有参数到builder</span>
<span class="hljs-keyword">for</span> (String key : map.keySet()) {
            builder.addFormDataPart(key, map.<span class="hljs-keyword">get</span>(key));
        }


   <span class="hljs-comment">//遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key</span>
        <span class="hljs-keyword">for</span> (String path : paths) {
            builder.addFormDataPart(<span class="hljs-string">"files"</span>, path, RequestBody.create(MEDIA_TYPE_PNG, <span class="hljs-keyword">new</span> File(path)));
        }


      <span class="hljs-comment">//构建请求体</span>
        RequestBody requestBody = builder.build();

 <span class="hljs-comment">//构建请求</span>
 Request request = <span class="hljs-keyword">new</span> Request.Builder()
                .url(url)<span class="hljs-comment">//地址</span>
                .post(requestBody)<span class="hljs-comment">//添加请求体</span>
                .build(); 

<span class="hljs-comment">//发送异步请求,同步会报错,Android4.0以后禁止在主线程中进行耗时操作</span>
client.newCall(request).enqueue(<span class="hljs-keyword">new</span> Callback() {
            @Override
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onFailure</span>(Request request, IOException e) {
                System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"request = "</span> + request.urlString());
                System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"e.getLocalizedMessage() = "</span> + e.getLocalizedMessage());
            }

            @Override
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onResponse</span>(Response response) throws IOException {
                <span class="hljs-comment">//看清楚是response.body().string()不是response.body().toString()</span>
                         System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"response = "</span> + response.body().<span class="hljs-keyword">string</span>());
                         }
        });</code>

基本实现思路就是这样了,更多请参考OkHttp文档,项目中我准备完全除去Xutils的其他部分,如文件下载部分。

知识拓展

List与HashMap区别
List可以保存多个相同或者不同的元素
HashMap则是以键值对(key-value)保存元素,当添加多个相同key的元素,之前的元素会被覆盖

这一点至关重要,Xutils以及KJFframework的设计都没有考虑到这一点,看似很好用,但当我要添加多张相同或者不同的图片文件作为参数传输给后台,我却需要定义很多的key,不然无论添加多少张图片结果却只能是最后一张

 

 

SpingMvc 上传图片核心代码:

 @RequestMapping(value="uploadPic")
 public @ResponseBody Messege uploadPic(@RequestParam(required = false) MultipartFile[] files,HttpServletRequest request){ 
  Messege messege=new Messege();
  String path = request.getSession().getServletContext()
    .getRealPath("/upload")
    + File.separator;
  System.out.println(path);
  if (files != null && files.length > 0) {
   for (MultipartFile f : files) {
    if (f.isEmpty()) {
     continue;

    } else {
     String fileName = f.getOriginalFilename();// 真实文件 名
     System.out.println(f.getContentType());
     try {
      FileUtils.copyInputStreamToFile(f.getInputStream(),
        new File(path + fileName));
      
      messege.setRet_code(200);
      messege.setRet_msg("上传图片成功");
     } catch (IOException e) {
      messege.setRet_code(0);
      messege.setRet_msg("上传图片");
      e.printStackTrace();
     }

    }

   }

  }
 
  
  
  
  return messege;
  
  
  
 }

spring-servlet.xml 配置文件

<bean id="multipartResolver"
  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="maxUploadSize" value="10485760000" />
 </bean>

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值