Retofit+Okhttp表单上传文件及参数处理大全

时间:2025-02-08 10:18:23

Retofit+Okhttp表单上传文件及参数处理大全

一、Retofit配置上传文件的方式

1. 仅参数上传

方式一
@FormUrlEncoded
@POST("upload")
Call<ResponseBody> uploadParams(@Field("username")String username,@Field("token")String token);
方式二
@FormUrlEncoded
@POST("upload")
Call<ResponseBody> uploadParams(@FieldMap Map<String,String> map);   
方式三
@POST("upload")
Call<ResponseBody> uploadParams(@Body RequestBody body);

2. 文件上传

单文件上传
 @Multipart
 @POST("upload")
Call<ResponseBody> uploadOneFile(@Part MultipartBody.Part body);

调用方式:

File file = new File("");

RequestBody fileRQ = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);

Call<ResponseBody> uploadCall = downloadService.uploadOneFile(part);
多文件上传
方式一
@Multipart
@POST("upload")
Call<ResponseBody> uploadFiles(@PartMap Map<String, RequestBody> map);

调用:

RequestBody fb = RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
RequestBody fileTwo = RequestBody.create(MediaType.parse("image/*"), new File(Environment.getExternalStorageDirectory()
                + file.separator + ""));
Map<String, RequestBody> map = new HashMap<>();
//这里的key必须这么写,否则服务端无法识别
map.put("file\"; filename=\""+ file.getName(), fileRQ);
map.put("file\"; filename=\""+ "", fileTwo);

Call<ResponseBody> uploadCall = downloadService.uploadFiles(map);
方式二
@Multipart
@POST("upload")
Call<ResponseBody> uploadFiles(@Part List<MultipartBody.Part> parts);

调用:

RequestBody fileRQ = RequestBody.create(MediaType.parse("image/*"), file);

MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);

RequestBody fb = RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
RequestBody fileTwo = RequestBody.create(MediaType.parse("image/*"), new File(Environment.getExternalStorageDirectory()
                + file.separator + ""));
MultipartBody.Part two=MultipartBody.Part.createFormData("one","",fileTwo);
List<MultipartBody.Part> parts=new ArrayList<>();
parts.add(part);
parts.add(two);

 Call<ResponseBody> uploadCall = downloadService.uploadFiles(parts);

3. 文件+参数混合上传

方式一
@Multipart
@POST("upload")
Call<ResponseBody> uploadFile(@Part("body") RequestBody body, @Part MultipartBody.Part file);

调用:

MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);
RequestBody fb =RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
Call<ResponseBody> uploadCall = downloadService.uploadFile(fb,part);
方式二
 @POST("upload")
 Call<ResponseBody> uploadFile(@Body RequestBody body);

调用:

        File file = new File("path");
        RequestBody fileRQ = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);

        RequestBody body=new MultipartBody.Builder()
                .addFormDataPart("userName","lange")
                .addFormDataPart("token","dxjdkdjkj9203kdckje0")
                .addFormDataPart("header",file.getName(),fileRQ)
                .build();
        Call<ResponseBody> uploadCall = downloadService.uploadFile(body);
        uploadCall.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.i("upload", response.isSuccessful() + "");
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {

            }
        });

二、Okhttp拦截器添加

Retrofit配置

import 
import 
import 
import 
import 
import 

class RetrofitHelper private constructor() {
    private var okHttpClient: OkHttpClient
    private var retrofit: Retrofit
    private val headerInterceptor: Interceptor
    private val logInterceptor: HttpLoggingInterceptor

    private object SingletonHolder {
        val helper = RetrofitHelper()
    }

    companion object {
        private var BASE_URL = ""
        private const val DEFAULT_CONNECT_TIME = 10
        private const val DEFAULT_WRITE_TIME = 15
        private const val DEFAULT_READ_TIME = 15

        const val TOKEN_KEY = "token"
        const val UID_KEY = "uid"
        const val LANGUAGE_KEY = "language"
        const val COUNTRY_KEY = "country"

        const val SUCCESS_CODE = 1

        val context = 
        val instance = 

    }

    init {
        headerInterceptor = Interceptor {
            val request = ().newBuilder()
                .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                .addHeader("Connection", "keep-alive")
                .addHeader("timestamp", (() / 1000).toString())  
                .build()

            (request)
        }
        ()
        logInterceptor = HttpLoggingInterceptor()
         = 

        okHttpClient = ()
            .connectTimeout(DEFAULT_CONNECT_TIME.toLong(), ) //连接超时时间
            .writeTimeout(DEFAULT_WRITE_TIME.toLong(), ) //设置写操作超时时间
            .readTimeout(DEFAULT_READ_TIME.toLong(), ) //设置读操作超时时间
            .addInterceptor(headerInterceptor)
            .addInterceptor(LoggingInterceptor())
            .sslSocketFactory(,)
            .build()
        retrofit = ()
            .client(okHttpClient) //设置使用okHttp网络请求
            .baseUrl(BASE_URL) //设置服务器路径
            .addConverterFactory(()) //添加转化库,默认是Gson
            .build()
    }



    fun <T> create(service: Class<T>?): T {
        return (service)
    }
}

日志拦截

import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

public class LoggingInterceptor implements Interceptor {
    private static final String TAG = "LoggingInterceptor";

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = ();
        Response response = (original);
        (TAG, ("...\n请求链接:%s\n请求方式:%s\n请求头:\n%s\n请求参数:\n%s\n响应码:%s\n请求响应:\n%s", (),
                (), getRequestHeaders(original), getRequestInfo(original), (), getResponseInfo(response)));
        return response;
    }

    /**
     * 打印请求头
     *
     * @param request 请求的对象
     */
    private String getRequestHeaders(Request request) {
        String str = "";
        if (request == null) {
            return str;
        }
        Headers headers = ();
        if (headers == null) {
            return str;
        }
        return ();
    }

    /**
     * 打印请求消息
     *
     * @param request 请求的对象
     */
    private String getRequestInfo(Request request) {
        String str = "";
        if (request == null) {
            return str;
        }
        RequestBody requestBody = ();
        if (requestBody == null) {
            return str;
        }
        if (requestBody instanceof MultipartBody) {
            return "MultipartBody不显示";
        }
        try {
            Buffer bufferedSink = new Buffer();
            (bufferedSink);
            Charset charset = ("utf-8");
            str = (charset);
        } catch (Exception e) {
            ();
        }
        return str;
    }

    /**
     * 打印返回消息
     *
     * @param response 返回的对象
     */
    private String getResponseInfo(Response response) {
        String str = "";
        if (response == null || !()) {
            return str;
        }
        ResponseBody responseBody = ();
        long contentLength = ();
        BufferedSource source = ();
        try {
            (Long.MAX_VALUE); // Buffer the entire body.
        } catch (Exception e) {
            ();
        }
        Buffer buffer = ();
        Charset charset = ("utf-8");
        if (contentLength != 0) {
            str = ().readString(charset);
        }
        return str;
    }
}

发送+接收数据拦截

import ;
import ;

import ;

import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

/**
 * 处理拦截
 */
public class SafeInterceptor implements Interceptor {
    private String TAG = "SafeInterceptor";

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = ();
        //指定域名不拦截
        if (().toString().endsWith("XXXX")) {
            return (request);
        }
        HashMap<String, String> needSignMap = new HashMap<>();
        //1.获取head数据
        getRequestHeaders(request, needSignMap);
        //2.获取queryMap数据
        getQuery(request, needSignMap);
        //3.获取mediaType:x-www-form-urlencoded,Body数据
        //4.获取mediaType:multipart/form-data,value 类型和 file 类型。
        getBody(request, needSignMap);
         newBuilder = ();
        ("X-Unique-Sign", sign);
        //数据加密
        RequestBody requestBody = ();
        if (requestBody != null) {
            if (requestBody instanceof FormBody) {
                (requestBody);
            } else if (requestBody instanceof MultipartBody) {
                (requestBody);
            } else {
                String postBodyString = bodyToString(requestBody);
                (TAG, "请求参数:" + postBodyString);
                if (!(postBodyString)) {
                    String type = ();
                    if ("Post".equalsIgnoreCase(type)){
                        ((("text/plain;charset=UTF-8"), allBase));
                    }else if ("Put".equalsIgnoreCase(type)){
                        ((("text/plain;charset=UTF-8"), allBase));
                    }
                }
            }
        }
        //7.返回数据
        request = ();
        Response response = (request);
        return getResponseString(response, sign, app_secret);
    }

    private void getBody(Request request, HashMap<String, String> needSignMap) {
        RequestBody requestBody = ();
        if (requestBody == null) return;
        MediaType type = ();
        if (type != null) {
            (TAG, "接口请求Type:" + type);
            if (requestBody instanceof FormBody) {
                for (int i = 0; i < ((FormBody) requestBody).size(); i++) {
                    String name = ((FormBody) requestBody).encodedName(i);
                    if (!"file".equalsIgnoreCase(name)) {
                        (name, ((FormBody) requestBody).encodedValue(i));
                    }
                }
            } else if (requestBody instanceof MultipartBody) {
                MultipartBody body = (MultipartBody) requestBody;
                HashMap<String, String> params = new HashMap<>();
                HashMap<String, String> files = new HashMap<>();
                for ( part : ()) {
                    RequestBody body1 = ();
                    Headers headers = ();
                    if (headers != null && () > 0) {
                        String[] split = (0).replace(" ", "").replace("\"", "").split(";");
                        if ( == 2) {
                            //文本
                            String[] keys = split[1].split("=");
                            try {
                                if ( > 1 && () < 1024) {
                                    String key = keys[1];
                                    String value = "";
                                    Buffer buffer = new Buffer();
                                    (buffer);
                                    value = buffer.readUtf8();
                                    (key, value);
                                }
                            } catch (IOException e) {
                                (TAG,"getBody multipart:"+());
                            }
                        } else if ( == 3) {
                            //文件
                            String fileKey = "";
                            String fileName = "";
                            String[] keys = split[1].split("=");
                            String[] names = split[2].split("=");
                            if ( > 1) fileKey = keys[1];
                            if ( > 1) fileName = names[1];
                            (fileKey, fileName);
                        }
                    }
                }
                (TAG,"文本参数:"+params);
                ("file");
                (TAG,"文件参数:"+files);
                (params);
            } else {
                if (().contains("x-www-form-urlencoded")) {
                    HashMap<String, String> urlencodedMap = new HashMap<>();
                    //buffer流
                    Buffer buffer = new Buffer();
                    try {
                        (buffer);
                        String oldParamsJson = buffer.readUtf8();
                        Gson gson = new Gson();
                        urlencodedMap = (oldParamsJson, );  //原始参数
                        (urlencodedMap);
                    } catch (IOException e) {
                        (TAG,"getBody form:"+());
                    }
                }
            }
        }


    }

    private void getQuery(Request request, HashMap<String, String> needSignMap) {
        Set<String> paramterSet = ().queryParameterNames();
        for (String itmeName : paramterSet) {
            String itemValue = ().queryParameter(itmeName);
            (itmeName, itemValue);
        }
    }

    private void getRequestHeaders(Request request, HashMap<String, String> signMap) {
        if (request != null) {
            Headers headers = ();
            if (headers != null) {
                String timestampValue = ("timestamp");
                if (!(timestampValue)) {
                    ("timestamp", timestampValue);
                }
            }
        }
    }

    private String bodyToString(final RequestBody request) {
        try {
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if (copy != null){
                (buffer);
            } else {
                return "";
            }
            return buffer.readUtf8();
        } catch (final IOException e) {
            (TAG, "bodyToString IOException");
            return "";
        }
    }


    /*处理响应*/
    private Response getResponseString(Response response, String sign, String app_secret) throws UnsupportedEncodingException {
        ResponseBody responseBody = ();
        if (responseBody != null) {
            long contentLength = ();
            //判断返回内容中data加密
            if (bodyEncoded(())) {
                BufferedSource source = ();
                try {
                    (Long.MAX_VALUE); // Buffer the entire body.
                } catch (IOException e) {
                    (TAG, "getResponseString IOException:"+ ());
                }
                Buffer buffer = ();

                Charset charset = ("UTF-8");
                MediaType contentType = ();
                if (contentType != null) {
                    try {
                        charset = (("UTF-8"));
                    } catch (UnsupportedCharsetException e) {
                        (TAG, ());
                    }
                }

                if (contentLength != 0) {
                    String res = ().readString(charset);

//                    (TAG, "响应数据:" + res);
                    BaseAResponse baseAsResponse = new Gson().fromJson(res, );
                    String secretData = ();
                    String result = secretData;
                    if (!(secretData)) {
                        String contentEncoding = ().get("Algorithm");
               
                      /*  if (!(result)){
                            BaseResponse response = new Gson().fromJson(result, );
                        }*/
                    } else {
                        result = res;
                    }
                    (TAG, "解密数据:" + result);

                    MediaType mediaType = ();
                    return ().body((
                            mediaType,
                            result
                    )).build();
                }
            }
        }
        return response;
    }

}

三、MultipartBody内部数据解析

直接上代码示例

kotlin

 if (requestBody is MultipartBody) {
            val params = mutableMapOf<String, String>()
            val files = mutableMapOf<String, String>()
            requestBody.parts().forEach {
                val body = it.body()
                it.headers()?.let {
                    val header = it.value(0)
                    val split = header.replace(" ", "").replace("\"", "").split(";")
                    when (split.size) {
                        2 -> {
                            //文本参数
                            val keys = split[1].split("=")
                            if (keys.size > 1 && body.contentLength() < 1024) {
                                val key = keys[1]
                                val buffer = Buffer()
                                body.writeTo(buffer)
                                val value = buffer.readUtf8()
                                params[key] = value
                            }
                        }
                        3 -> {
                            //文件
                            val fileKeys = split[1].split("=")
                            val fileKey = if (fileKeys.size > 1) {
                                fileKeys[1]
                            } else ""
                            val nameValue = split[2].split("=")
                            val fileName = if (nameValue.size > 1) nameValue[1] else ""
                            files[fileKey] = fileName
                        }
                    }
                }
            }
            println("文件-->$files")
            println("文本-->$params")
        }

java

if (requestBody instanceof MultipartBody) {
            MultipartBody body = (MultipartBody) requestBody;
            Map<String, String> params = new HashMap<>();
            Map<String, String> files = new HashMap<>();
            for (MultipartBody.Part part : body.parts()) {
                RequestBody body1 = part.body();
                Headers headers = part.headers();
                if (headers != null && headers.size() > 0) {
                    String[] split = headers.value(0).replace(" ", "").replace("\"", "").split(";");
                    if (split.length == 2) {
                        //文本
                        String[] keys = split[1].split("=");
                        if (keys.length > 1 && body1.contentLength() < 1024) {
                            String key = keys[1];
                            String value = "";
                            Buffer buffer = new Buffer();
                            body1.writeTo(buffer);
                            value = buffer.readUtf8();
                            params.put(key, value);
                        }
                    } else if (split.length == 3) {
                        //文件
                        String fileKey = "";
                        String fileName = "";
                        String[] keys = split[1].split("=");
                        String[] names = split[2].split("=");
                        if (keys.length > 1) fileKey = keys[1];
                        if (names.length > 1) fileName = names[1];
                        files.put(fileKey, fileName);
                    }
                }
            }
            System.out.println("文本参数-->" + params);
            System.out.println("文件参数-->" + files);
        }