最近在做Android项目,使用的是MVP+Retrofit+rxjava+dagger的项目架构,RestFul 服务使用的.Net平台的WebApi。由于业务中需要有多文件上传的功能。所以在这里记载一下,便于以后查阅。
Android端Retrofit api 定义
在这次上传中,我们将实体类数据和文件数据一起上传到服务端。所以只写一个api就好
<code>()</code>
<code>Observable<HttpResult<String>> addEvent(() Event entity, ()List<MultipartBody.Part> parts);</code>
读取文件并将其转换成MuiltipartBody.Part 列表
<code>List<MultipartBody.Part> getFilesMap() {</code>
<code> </code><code>= ArrayList<MultipartBody.Part>();</code>
<code> </code><code>File file = ;</code>
<code> </code><code>{</code>
<code> </code><code>(!= && .size() > ) {</code>
<code> </code><code>(String path : ) {</code>
<code> </code><code>file = File(path);</code>
<code> </code><code>RequestBody requestBody = RequestBody.(MediaType.(), file);</code>
<code> </code><code>MultipartBody.Part part = MultipartBody.Part.(, file.getName(), requestBody);</code>
<code> </code><code>.add(part);</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>} (Exception e) {</code>
<code> </code><code>e.printStackTrace();</code>
<code> </code><code>}</code>
<code> </code><code>;</code>
<code>}</code>
调用Retrofit 进行网络请求,并将实体类数据和文件数据一并发送到 服务端
<code>addEvent() {</code>
<code> </code><code>Event entity = .getEntity();</code>
<code> </code><code>List<MultipartBody.Part> fileMap = .getFilesMap();</code>
<code> </code><code>.clear();</code>
<code> </code><code>Subscription subscription = .getRetrofitInstance()</code>
<code> </code><code>.create(EventInterface.)</code>
<code> </code><code>.addEvent(entity, fileMap)</code>
<code> </code><code>.subscribeOn(.io()).observeOn(.ui()).subscribe(Subscriber<HttpResult<String>>() {</code>
<code> </code><code>onCompleted() {</code>
<code> </code><code>}</code>
<code> </code><code>onError(Throwable e) {</code>
<code> </code><code>.setLoadingIndicator();</code>
<code> </code><code>e.printStackTrace();</code>
<code> </code><code>onNext(HttpResult<String> httpResult) {</code>
<code> </code><code>(httpResult.getResultCode() != ConstData.HttpResult.) {</code>
<code> </code><code>.setLoadingIndicator();</code>
<code> </code><code>} {</code>
<code> </code><code>}</code>
<code> </code><code>});</code>
<code> </code><code>.add(subscription);</code>
在webapi 端对文件以及数据进行接收。由上面转化MultipartBody 那一个环节我们可以看到,传到服务端的数据是以HTTP形式传送的。数据类型都是multipart/form-data类型的。所以我们在服务端要使用http相关协议来进行接收。
<code> </code><code>[HttpPost]</code>
<code> </code><code>public</code> <code>HttpResult<string> AddEvent()</code>
<code> </code><code>{</code>
<code> </code><code>//获取EventET 的属性</code>
<code> </code><code>HttpRequest request = HttpContext.Current.Request;</code>
<code> </code><code>string entity = request.Form[</code><code>0</code><code>];</code>
<code> </code><code>BaseBN baseBN = </code><code>new</code> <code>BaseBN();</code>
<code> </code><code>EventET et = baseBN.CTJsonSerializer<EventET>(entity);</code>
<code> </code><code>SystemBN bn = </code><code>new</code> <code>SystemBN();</code>
<code> </code><code>et.EVENT_ID = bn.CreateID(</code><code>"EVENT"</code><code>, HaiQu.N, </code><code>"EVENT_ID"</code><code>, </code><code>"EVENT"</code><code>, EventType.YiYou);</code>
<code> </code><code>List<string> addr = </code><code>new</code> <code>List<string>();</code>
<code> </code><code>//获取上传的文件</code>
<code> </code><code>HttpFileCollection coll = request.Files;</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i < coll.Count; i++)</code>
<code> </code><code>{</code>
<code> </code><code>HttpPostedFile file = coll.Get(i);</code>
<code> </code><code>String filename = file.FileName.Substring(file.FileName.LastIndexOf(</code><code>"\\"</code><code>) + </code><code>1</code><code>);</code>
<code> </code><code>if</code> <code>(!Directory.Exists(System.Web.HttpContext.Current.Server.MapPath(</code><code>"~/Upload/"</code> <code>+ et.EVENT_ID)))</code><code>//如果不存在就创建file文件夹</code>
<code> </code><code>{</code>
<code> </code><code>Directory.CreateDirectory(System.Web.HttpContext.Current.Server.MapPath(</code><code>"~/Upload/"</code> <code>+ et.EVENT_ID));</code>
<code> </code><code>}</code>
<code> </code><code>string fileSavePath = string.Format(</code><code>"~/Upload/"</code> <code>+ et.EVENT_ID + </code><code>"/{0}"</code><code>, filename);</code>
<code> </code><code>file.SaveAs(System.Web.HttpContext.Current.Server.MapPath(fileSavePath));</code>
<code> </code><code>addr.Add(fileSavePath);</code>
<code> </code><code>EventBN eventBN = </code><code>new</code> <code>EventBN();</code>
<code> </code><code>HttpResult<string> result = eventBN.AddEvent(et, addr, HaiQu.N);</code>
<code> </code><code>return</code> <code>result;</code>
<code> </code>
这里有几点需要注意,实体类的数据,传输到服务端的时候,会以JSON字符串的形式传输到后台。这样的话,在后台使用的时候,需要对其进行反序列化。
另外,上传的文件,在HTTP中是以集合的形式存在,直接取出来,存储到本地就好。有一点需要注意的是,由于IIS对上传文件的限制,需要提前修改一下允许上传文件的上限。要不然,会上传不成功(这些都是已经踩过的坑)。
说在最后,其实上传文件很简单,网上有很多的大神已经讲解的非常详细。之所又自己啰嗦了一下,是因为,在做的过程中,踩了很多的坑,而且网上大多数人都只写了Android端,没有写服务端。再加上,.NET WebApi 用的人比较小众,所以就记录了一下。以后有时间会补上Spring 作为服务端的写法。以及Struts作为服务端的写法。
今天就到这里吧。
本文转自Eumenides_s 51CTO博客,原文链接:http://blog.51cto.com/xiaoshuaigege/1878634,如需转载请自行联系原作者