如何正确管理改造POST请求?

时间:2018-12-18 13:48:42

标签: android http retrofit okhttp

实际上,我正在尝试将文本文件发布到我的服务器,并且当我发送文件但我没有得到响应时,我将能够处理该错误(如果文件已发送到网络已关闭,因此服务器收到了文件,但设备不知道)

因为现在我遇到了一个问题,因为如果设备返回在线状态时我没有得到响应,它将再次发送相同的文件,并且我会阻止它。

似乎在连接失败或类似的情况下隐式重试发送文件。

这是我使用onClick发送文件的方法:

 public void sendPost() {
        @SuppressLint({"SdCardPath", "DefaultLocale"}) final File file = new File("/data/data/com.example.igardini.visualposmobile/files/"+String.format("%03d", Integer.valueOf(nTerminalino))+"_"+nTavoli.getText().toString()+".txt");

        final MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);

        final RequestBody fbody = RequestBody.create(MediaType.parse("text/*"), file);
        builder.addFormDataPart(String.format("%03d", Integer.valueOf(nTerminalino))+"_"+nTavoli.getText().toString(), file.getName(),fbody);

        final MultipartBody requestBody = builder.build();

        final APIService apiService = ApiUtils.getAPIService(ipCASSA);

        final Call<Void> calls = apiService.savePost(requestBody);



        calls.enqueue(new Callback<Void>() {
            @Override
            public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
                if (response.isSuccessful()) {
                    Log.i("RESPONSE: ", response.toString());


                    Print();
                    dialogLoading.dismiss();
                    Runtime.getRuntime().gc();


//                    checkFile task = new checkFile();
//                    task.execute();

                }else {
                    Toast.makeText(pterm.this,"ERRORE",Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
                    if(t instanceof IOException) {
                        Log.e("TAG", t.toString());
                        MediaPlayer mpFound = MediaPlayer.create(pterm.this, R.raw.errorsound);
                        mpFound.start();
                        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                        if (v.hasVibrator()) {
                            v.vibrate(6000);
                        }
                        new GlideToast.makeToast(pterm.this, "CONNESSIONE FALLITA!", GlideToast.LENGTHLONG, GlideToast.FAILTOAST).show();
                        dialogLoading.dismiss();
                    }

            }
        });
    }

这是我其他有用的类:

class ApiUtils {

    private ApiUtils() {}



    static APIService getAPIService(String ipCASSA) {

        String BASE_URL = "http://"+ipCASSA+"/web/";

        final OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10000, TimeUnit.MILLISECONDS)
                .writeTimeout(10000, TimeUnit.MILLISECONDS)
                .readTimeout(10000, TimeUnit.MILLISECONDS)
                .retryOnConnectionFailure(false)
                .build();


        return RetrofitClient.getClient(BASE_URL,okHttpClient).create(APIService.class);
    }
}

public interface APIService {

    @POST("CART=PTERM")
    Call<Void> savePost(@Body RequestBody text);

}

class RetrofitClient {

    private static Retrofit retrofit = null;


    static Retrofit getClient(String baseUrl, OkHttpClient okHttpClient) {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

1 个答案:

答案 0 :(得分:1)

在这种情况下,我会向设备添加某种设备生成的随机ID,并将其与请求一起发送。

在服务器端,我将更改逻辑以首先尝试使用此ID在DB中定位文件,如果没有,则将其存储并返回OK状态以及服务器端ID(稍后可能会派上用场)。

如果根据要求提供了具有ID的文件,只需返回状态为200的服务器端ID-这样就不会存储两次。

您甚至可以走得更远-如果您的连接不稳定(从描述中可以看出),您甚至可以进行单独的REST调用,以通过生成的ID或校验和检查文件是否在服务器端,如果不是,则开始发送-它将使女巫安全。

不必生成ID-例如,它可以是文件的校验和。无论哪种方式对您来说更轻松。

要生成ID,您可以使用Android的UUID https://developer.android.com/reference/java/util/UUID

对于校验和,请检查以下答案: How to generate an MD5 checksum for a file in Android?

顺便说一句-我不会做10秒的超时限制-太多了,用户体验将很糟糕