Как отправить изображение большого файла через модификацию, которая уже работает в Postman и для сервера nginx нет ограничений? - PullRequest
1 голос
/ 23 апреля 2020

Я успешно создал одну демонстрацию для загрузки изображения через API. Если я выберу мобильный скриншот, он с удовольствием работает. но если я выберу большой файл, он не будет работать, за исключением: 413

onResponse: [size=208 text=<html>\r\n<head><title>413 Request Entity Too Large</title></head>…]

Итак, я искал эту проблему и нашел тысячи решений. Все говорят одно и то же. Пожалуйста, настройте конфигурацию на стороне сервера, чтобы расширить лимит это работает! Как? И это означает, что больше нет необходимости выполнять настройку на веб-сервере.

Теперь я сомневаюсь, что само по себе Retrofit не допускает слишком большие файлы. Тогда я должен попробовать с AsyncTask или может быть Volley?

Код: Модифицированный клиент:

package com.androidbuts.api;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;


/**
 * @author Pratik Butani
 */
public class RetroClient {

    /**
     * Upload URL of your folder with php file name...
     * You will find this file in php_upload folder in this project
     * You can copy that folder and paste in your htdocs folder...
     */
    private static final String ROOT_URL = "https://b2cprintappstg.e-arc.com/microservice/";
    /**
     * Get Retro Client
     *
     * @return JSON Object
     */

    static Gson gson = new GsonBuilder()
            .setLenient()
            .create();

    public RetroClient() {

    }

    private static Retrofit getRetroClient() {
        return new Retrofit.Builder()
                .baseUrl(ROOT_URL)
                .client(getHeader())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }

    public static ApiService getApiService() {
        return getRetroClient().create(ApiService.class);
    }

    public static OkHttpClient getHeader() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient okClient = new OkHttpClient.Builder()
                .readTimeout(100, TimeUnit.SECONDS)
                .connectTimeout(100, TimeUnit.SECONDS)
                .writeTimeout(100, TimeUnit.SECONDS)
                .addInterceptor(interceptor)
                .addNetworkInterceptor(
                        new Interceptor() {
                            @Override
                            public Response intercept(Interceptor.Chain chain) throws IOException {
                                Request request = null;


                                Request original = chain.request();
                                // Request customization: add request headers
                                Request.Builder requestBuilder = original.newBuilder()
                                        .addHeader("ClientID", "xxxxxx")
                                        .addHeader("x-access-token", "3uYch6X1i2OuRd3DvBPvvwiMRqPboBdRt/PbSiP0KFB4eaQQFg==")
                                        .addHeader("PartnerID", "fV17XLswDUwlU9q9ofx4pkhezw==");


                                request = requestBuilder.build();

                                return chain.proceed(request);
                            }
                        })
                .build();
        return okClient;

    }
}

Служба API:

public interface ApiService {

    /*
    Retrofit get annotation with our URL
    And our method that will return us the List of Contacts
    */
    @Multipart
    @POST("user/new/api/design/files")

    Call<ResponseBody> uploadImage(@Part MultipartBody.Part file,
                                   @Part("design_id ") String designId);
}

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

попробуйте проверить сервер ngnix. и добавить конфигурацию

0 голосов
/ 23 апреля 2020

Я думаю, что виновником здесь является тайм-аут, который вы установили для OkHttp. Я бы сказал, установить время ожидания, чтобы иметь большее значение, как требуется.

OkHttpClient okClient = new OkHttpClient.Builder()
    .readTimeout(600, TimeUnit.SECONDS)
    .connectTimeout(600, TimeUnit.SECONDS)
    .writeTimeout(600, TimeUnit.SECONDS)
    .addInterceptor(interceptor)
    .addNetworkInterceptor(
            new Interceptor() {
                @Override
                public Response intercept(Interceptor.Chain chain) throws IOException {
                    Request request = null;


                    Request original = chain.request();
                    // Request customization: add request headers
                    Request.Builder requestBuilder = original.newBuilder()
                            .addHeader("ClientID", "xxxxxx")
                            .addHeader("x-access-token", "3uYch6X1i2OuRd3DvBPvvwiMRqPboBdRt/PbSiP0KFB4eaQQFg==")
                            .addHeader("Content-type", "multipart/form-data; boundary=" + "SomeRandomConstant");
                            .addHeader("PartnerID", "fV17XLswDUwlU9q9ofx4pkhezw==");


                    request = requestBuilder.build();

                    return chain.proceed(request);
                }
            })
    .build();

Более того, вы можете рассмотреть возможность установки уровня журнала в interceptor на NONE, как , предложенное здесь .

interceptor.setLevel(HttpLoggingInterceptor.Level.NONE);

Я цитирую Джейка Уортона из упомянутой выше проблемы.

Вызывая .setLogLevel(RestAdapter.LogLevel.FULL), вы заставляете Retrofit буферизовать все тело запроса в память, чтобы он мог регистрироваться. Это то, что делает вызов readBodyToBytesIfNe Необходимый в трассировке стека.

Включение ведения журнала таким образом, должно быть сделано только при отладке.

Также, пожалуйста, убедитесь, что вы добавили правильное Content-Type в заголовке вашего запроса.

.addHeader("Content-type", "multipart/form-data; boundary=" + "SomeRandomConstant");

Пожалуйста, см. Ответ здесь , чтобы получить больше информации о настройке типа контента.

Надеюсь, это поможет!

...