Retrofit实现图文上传至服务器

前言:现在大多数的项目中都涉及图片+文字上传了,下面请详见实现原理:

开发环境:AndroidStudio

1.引入依赖

compile 'com.squareup.retrofit2:retrofit:2.1.0'  

2.网络权限

<uses-permission android:name="android.permission.INTERNET" />  

3.创建上传对象OkHttpClient :

private static final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain
.request()
.newBuilder()
.build();
return chain.proceed(request);
}
})
.readTimeout(10, TimeUnit.SECONDS)//设置读取超时时间
.writeTimeout(10, TimeUnit.SECONDS)//设置写的超时时间
.connectTimeout(15, TimeUnit.SECONDS)//设置连接超时时间
.build();

4.上传图片的公有方法

    private synchronized final static void uploadImgAndParameter(Map<String, Object> map, String url,
final UIDataListener listener) { // mImgUrls为存放图片的url集合
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); if (null != map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() != null) {
if (entry.getValue() instanceof File) {
File f = (File) entry.getValue();
builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
} else {
builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
}
} }
}
//创建RequestBody
RequestBody body = builder.build(); // MultipartBody requestBody = builder.build();
//构建Request请求
final Request request = new Request.Builder()
.url(url)//地址
.post(body)//添加请求体
// .post(requestBody)//添加请求体
.build();
client.newCall(request).enqueue(new okhttp3.Callback() { @Override
public void onResponse(Call call, final Response response) throws IOException {
if (response.isSuccessful()) {//判断是否成功
final String data = response.body().string();//string()仅可调用一次。否则报IllegalStateException: closed异常
Log.i("file1", "上传照片成功-->" + data);
onSuccess(listener, data);
call.cancel();//上传成功取消请求释放内存
}
}
@Override
public void onFailure(Call call, final IOException e) { Log.i("file2", "上传失败-->" + e.getMessage());
String msg = e.getMessage();
if (msg == null || msg.equals("timeout")) {
onError(listener, "网络不稳定请求超时!");
} else {
onError(listener, e.getMessage());
}
call.cancel();//上传失败取消请求释放内存
}
});
}

//注意:添加手机图片,别忘了添加SD卡权限

5.全部代码:

public class HttpUtil {

    private static final Handler handler = new Handler(Looper.getMainLooper());

    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/*");

    private static final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain
.request()
.newBuilder()
.build();
return chain.proceed(request);
}
})
.readTimeout(10, TimeUnit.SECONDS)//设置读取超时时间
.writeTimeout(10, TimeUnit.SECONDS)//设置写的超时时间
.connectTimeout(15, TimeUnit.SECONDS)//设置连接超时时间
.build(); /**
* 实例--》添加商品
*/
public static void addCoupon( int shopperId,String shopperName,
File file, final UIDataListener listener) {
String url = "shopappajx/shopAppCouponAction_saveCoupon.htm";
Map<String, Object> map = new HashMap<>();
map.put("shopperId", shopperId);
map.put("shopperName", shopperName);
map.put("couponImage", file);//商品图片
uploadImgAndParameter(map, url, listener);
} //上传图片共有方法
private synchronized final static void uploadImgAndParameter(Map<String, Object> map, String url,
final UIDataListener listener) { // mImgUrls为存放图片的url集合
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); if (null != map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() != null) {
if (entry.getValue() instanceof File) {
File f = (File) entry.getValue();
builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
} else {
builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
}
} }
}
//创建RequestBody
RequestBody body = builder.build(); // MultipartBody requestBody = builder.build();
//构建Request请求
final Request request = new Request.Builder()
.url(url)//地址
.post(body)//添加请求体
// .post(requestBody)//添加请求体
.build();
client.newCall(request).enqueue(new okhttp3.Callback() { @Override
public void onResponse(Call call, final Response response) throws IOException {
if (response.isSuccessful()) {//判断是否成功
final String data = response.body().string();//string()仅可调用一次。否则报IllegalStateException: closed异常
Log.i("file1", "上传照片成功-->" + data);
onSuccess(listener, data);
call.cancel();//上传成功取消请求释放内存
}
}
@Override
public void onFailure(Call call, final IOException e) { Log.i("file2", "上传失败-->" + e.getMessage());
String msg = e.getMessage();
if (msg == null || msg.equals("timeout")) {
onError(listener, "网络不稳定请求超时!");
} else {
onError(listener, e.getMessage());
}
call.cancel();//上传失败取消请求释放内存
}
});
} private final static void onSuccess(final UIDataListener listener, final String data) {
handler.post(new Runnable() {
public void run() {
// 需要在主线程的操作。
listener.onSuccess(data);
}
});
} private final static void onError(final UIDataListener listener, final String msg) {
if (null != listener) {
handler.post(new Runnable() {
public void run() {
// 需要在主线程的操作。
listener.onFailure(msg);
}
});
}
} public interface UIDataListener {
//网络请求成功
void onSuccess(String data); //网络请求失败
void onFailure(String errorMassage);
}
}

Retrofit实现图文上传至服务器的更多相关文章

  1. 【Android实战】----基于Retrofit实现多图片/文件、图文上传

    本文代码详见:https://github.com/honghailiang/RetrofitUpLoadImage 一.再次膜拜下Retrofit Retrofit不管从性能还是使用方便性上都非常屌 ...

  2. DedeCMS使用方法----如何将网站上传到服务器

    我们如果在本地已经把网站做好了,上传到服务器上去的正确姿势是什么样的呢?简单的很~跟着我的步调来~ 方法一(推荐此方法): 1.把你本地所有的文件压缩,上传至服务器上的根目录,再解压. 2.把本地的数 ...

  3. 使用html5 FileReader获取图片,并异步上传到服务器(不使用iframe)

    使用html5 FileReader获取图片,并异步上传到服务器(不使用iframe)   原理: 1.使用FileReader 读取图片的base64编码 2.使用ajax,把图片的base64编码 ...

  4. Phpcms V9网站从本地上传到服务器需要修改的地方

    网站在本地做好后要迁移到服务器上:网站在发展的过程中,很可能多次的修改域名.那么在Phpcms V9中我们要怎么进行设置呢 请进行以下步骤的修改: Phpcms V9网站上传到服务器具体方法如下:  ...

  5. java文件上传到服务器

    最近项目中使用到了文件从本地到服务器的功能.其实是为了解决目前浏览器不支持获取本地文件全路径.不得已而想到上传到服务器的固定目录,从而方便项目获取文件,进而使程序支持EXCEL批量导入数据. 在前台界 ...

  6. Maven配置jar(war)包自动打包上传Maven服务器的配置

    Maven配置jar(war)包自动打包上传Maven服务器的配置 创建jar(war)包工程 创建一个maven工程 在工程中穿件一个测试类 配置pom.xml <distributionMa ...

  7. HTML5 文件域+FileReader 分段读取文件并上传到服务器(六)

    说明:使用Ajax方式上传,文件不能过大,最好小于三四百兆,因为过多的连续Ajax请求会使后台崩溃,获取InputStream中数据会为空,尤其在Google浏览器测试过程中. 1.简单分段读取文件为 ...

  8. HTML5 文件域+FileReader 读取文件并上传到服务器(三)

    一.读取文件为blob并上传到服务器 HTML <div class="container"> <!--读取要上传的文件--> <input type ...

  9. HTML5 Canvas前台压缩图片并上传到服务器

    1.前台代码: <input id="fileOne" type="file" /> <input id="btnOne" ...

随机推荐

  1. Python——单例设计模式

    单例设计模式: 让类创建的对象,在系统中只有唯一的实例, 使用python类内置的__new__()方法实现,__new__()方法在创建对象时会被自动调用,通过重写__new__()方法,使得无论用 ...

  2. vue-tree 组织架构图/树形图自动生成(含添加、删除、修改)

    项目中用代码生成组织架构图  有新增,编辑,删除的功能            生成树形图的组件git-hub地址: https://github.com/tower1229/Vue-Tree-Char ...

  3. 自动化测试接口PYTHON

      在开发测试中经常会遇到接口迭代和代码重构,一个无关紧要的改动往往会引起整个项目的运行.现有的接口测试中往往只是针对单一接口的测试,可是业务的连贯性是非常紧密的,比如:用户从登陆,获取商品信息,下单 ...

  4. SD341X-SD343H管网法兰式伸缩蝶阀厂家,SD341X-SD343H管网法兰式伸缩蝶阀价格 - 专题栏目 - 无极资讯网

    无极资讯网 首页 最新资讯 最新图集 最新标签   搜索 SD341X-SD343H管网法兰式伸缩蝶阀 无极资讯网精心为您挑选了(SD341X-SD343H管网法兰式伸缩蝶阀)信息,其中包含了(SD3 ...

  5. JAVA学习3:Eclipse中集成Tomcat

    问题: 很多时候在Eclipse中启动Tmocat后,不能访问本机的localhost:8080主页,并且其他项目也不能访问. 原因: 打开Tomcat下的webapp后也找补到项目目录,这是因为Ec ...

  6. SeaJS结合javascript面向对象使用笔记(一)

    Sea.JS Seajs结合javascript面向对象 所需页面 /app/index.html /lib/factory.js /lib/sea.js /lib/constructor.js /j ...

  7. nginx启动,停止,重启

    Nginx的启动.停止与重启   启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@LinuxServer sbin]# /usr/local/nginx/ ...

  8. 深入理解JavaScript系列(49):Function模式(上篇)

    介绍 本篇主要是介绍Function方面使用的一些技巧(上篇),利用Function特性可以编写出很多非常有意思的代码,本篇主要包括:回调模式.配置对象.返回函数.分布程序.柯里化(Currying) ...

  9. Firebird Procedure 带返回的存储过程

    火鸟定义带返回的存储过程是这样,先定义返回结果字段列表,然后为返回字段一一赋值,当你需要返回一行时,就suspend. 当需要返回多行时,就再次为返回字段变量赋值,suspend. 示例: creat ...

  10. [转]Add Bootstrap Glyphicon to Input Box

    本文转自:http://stackoverflow.com/questions/18838964/add-bootstrap-glyphicon-to-input-box How can I add ...