图片文件上传接口 的retrofit 实现
背景
上传图片需要一个后台server来接收图片
在这里 找了一个提供服务的平台 :果创云
做项目用果创云,立即拥有你的低代码开发套装!
图片文件上传接口 App.CDN.UploadImg
-
接口地址:http://hn216.api.yesapi.cn/?s=App.CDN.UploadImg
-
接口描述: 通过表单方式上传图片。如有需要,也可以使用二制流application/octet-stream格式上传。上传后,可以在小白平台-数据-素材库查看已上传的图片文件
接口描述
请求(需要用表单方式传文件file):
{你的接口域名}/?s=App.CDN.UploadImg&app_key={你的app_key}&sign={动态签名}
返回:
{
"ret": 200,
"data": {
"err_code": 0,
"err_msg": "",
"url": "http://cdn7.okayapi.com/20170920223113_62b11e9002a749d4d468824b0c10bbd6"
},
"msg": ""
}
HTML表单示例:
<form class="form-horizontal" action="http://api.okayapi.com{你的接口域名}/?s=App.CDN.UploadImg&app_key=xxxxxxx&sign=xxxxx" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit" class="btn btn-success">upload</button>
</form>
retrofit的使用
public interface FileService {
int DEFAULT_TIMEOUT = 20 * 1000;
public String app_key ="demo";
public String NEWS_BASE_URL = "http://hd215.api.yesapi.cn/";
public String API = "&app_key="+app_key;
public String UPLOAD_URL = "?s=App.CDN.UploadImg"+API;
//上传图片 1
@Multipart
@POST(UPLOAD_URL)
Observable<Result<CustomData>> uploadPhoto(@Part MultipartBody.Part file);
//图片上传 2
@Multipart
@POST(UPLOAD_URL)
Observable<UpLoadImageEntity> uploadPhotopic(@Part List<MultipartBody.Part> partList);
//上传图片
@Multipart
@POST("upload")
Observable<String> uploadPhoto(@QueryMap Map<String, String> options, @Part MultipartBody.Part file);
//上传多图或单图
@Multipart
@POST("upload")
Observable<String> uploadPhoto(@PartMap Map<String, RequestBody> body);
@Streaming
@GET
Observable<ResponseBody> download(@Url String url);
}
/**
* 数据示例
* 返回:
* {
* "ret": 200,
* "data": {
* "err_code": 0,
* "err_msg": "",
* "url": "http://cdn7.okayapi.com/20170920223113_62b11e9002a749d4d468824b0c10bbd6"
* },
* "msg": ""
* }
*/
public class Result<T> {
private int ret;
private String msg;
private T data;
public int getRet_code() {
return ret;
}
public void setRet_code(int ret) {
this.ret = ret;
}
public T getResult() {
return data;
}
public void setResult(T data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "Result{" +
"ret_code=" + ret +
", result=" + data +
", msg=" + msg +
'}';
}
}
public abstract class CustomObserver< T extends Result> implements Observer<T> {
private List<Disposable> disposableList;
private SmartRefreshLayout smartRefreshLayout;
private BaseViewModel baseViewModel;
private ShimmerRecyclerView shimmerRecyclerView;
public CustomObserver() {
}
public CustomObserver(ShimmerRecyclerView shimmerRecyclerView) {
this.shimmerRecyclerView = shimmerRecyclerView;
}
public CustomObserver(BaseViewModel baseViewModel) {
this.baseViewModel = baseViewModel;
}
public CustomObserver(List<Disposable> disposableList, BaseViewModel baseViewModel) {
this.disposableList = disposableList;
this.baseViewModel = baseViewModel;
}
public CustomObserver(List<Disposable> disposableList) {
this.disposableList = disposableList;
}
public CustomObserver(SmartRefreshLayout smartRefreshLayout) {
this.smartRefreshLayout = smartRefreshLayout;
}
public CustomObserver(SmartRefreshLayout smartRefreshLayout, BaseViewModel baseViewModel) {
this.smartRefreshLayout = smartRefreshLayout;
this.baseViewModel = baseViewModel;
}
@Override
public void onSubscribe(Disposable d) {
if (disposableList != null) {
disposableList.add(d);
}
}
@Override
public void onNext( T response) {
ZLog.i(response.toString());
dismissProgress();
if (response != null){
if (SUCCESS == response.getRet_code()){
//ZLog.i("ok -- no_error_code contontext## \n "+response.getContent().toString());
onSuccess(response);
}else {
onError(TextUtils.isEmpty(response.getMsg()) ? "请求数据失败" : response.getMsg());
}
}
}
@Override
public void onError(Throwable e) {
dismissProgress();
onError(e.toString());
}
@Override
public void onComplete() {
//ZLog.d();
}
private void dismissProgress() {
ZLog.d("dismissProgress");
if (smartRefreshLayout != null) {
smartRefreshLayout.finishLoadMore();
smartRefreshLayout.finishRefresh();
}
if (baseViewModel != null) {
baseViewModel.dismissDialog();
}
if (shimmerRecyclerView != null) {
shimmerRecyclerView.hideShimmerAdapter();
}
}
/**
* 请求成功
*
* @param response 服务器返回的数据
*/
abstract public void onSuccess(T response);
public abstract void onError(String err_msg);
}
public class CustomData {
private int err_code;
private String err_msg;
private String url;
public int getErr_code() {
return err_code;
}
public void setErr_code(int err_code) {
this.err_code = err_code;
}
public String getErr_msg() {
return err_msg;
}
public void setErr_msg(String err_msg) {
this.err_msg = err_msg;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Data{" +
"err_code=" + err_code +
", err_msg='" + err_msg + '\'' +
", url=" + url +
'}';
}
}
public class UploadApi {
private Retrofit retrofit;
private FileService service;
private UploadApi() {
File cacheFile = new File(BaseApplication.getInstance().getCacheDir(), "cache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 100); //100Mb
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
// .addInterceptor(loggingInterceptor)
.addInterceptor(new MyLoggingInterceptor())
.addNetworkInterceptor(new HttpCacheInterceptor())
.cache(cache)
.build();
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").serializeNulls().create();
retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(NEWS_BASE_URL)
.build();
service = retrofit.create(FileService.class);
}
// 创建单例
private static class SingletonHolder {
private static final UploadApi INSTANCE = new UploadApi();
}
public static synchronized FileService getApiService() {
return SingletonHolder.INSTANCE.service;
}
class HttpCacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetworkUtil.isNetworkAvailable(BaseApplication.getInstance().getBaseContext())) { //没网强制从缓存读取
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response originalResponse = chain.proceed(request);
if (NetworkUtil.isNetworkAvailable(BaseApplication.getInstance().getBaseContext())) {
//有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置
String cacheControl = request.cacheControl().toString();
return originalResponse.newBuilder()
.header("Cache-Control", cacheControl)
.removeHeader("Pragma")
.build();
} else {
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=2419200")
.removeHeader("Pragma")
.build();
}
}
}
}