1

我成功创建了一个通过 API 上传图片的演示。如果我选择移动屏幕截图,它会很高兴地工作。但如果我选择大文件,则它不起作用,例外是:413

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

所以,我搜索了这个问题并找到了数千个解决方案。每个人都在说同样的话。 请在服务器端进行配置以扩展限制

但我的甜蜜而简单的问题是:无论哪个图像不适用于改造,我尝试使用邮递员并且它正在工作!如何?这意味着无需在 Web 服务器中进行额外的配置。

现在,我怀疑改造本身可能不允许这么大的文件。那么我应该尝试使用 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);
}
4

2 回答 2

0

尝试检查 ngnix 服务器。并添加配置

于 2020-04-25T14:07:41.560 回答
0

我认为这里的罪魁祸首是您为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();

此外,您可能会考虑按照此处的建议在interceptortoNONE中设置日志级别。

interceptor.setLevel(HttpLoggingInterceptor.Level.NONE);

我从上述问题中引用了 JakeWharton。

通过调用.setLogLevel(RestAdapter.LogLevel.FULL),您强制改造将整个请求正文缓冲到内存中,以便它可以记录。这就是在堆栈跟踪中调用 readBodyToBytesIfNecessary 所做的。

只有在调试时才应该启用这样的日志记录。

另外,请确保您已Content-Type在请求标头中添加了权限。

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

在此处查看答案以获取有关设置内容类型的更多信息。

我希望这会有所帮助!

于 2020-04-23T17:34:58.230 回答