0

我正在更新最初使用 Apache HTTP 客户端构建的代码,以改用 Retrofit。我遇到问题的代码块将本地应用程序数据库的副本上传到我的服务器。此过程的一部分是使用在 POST 身份验证中发送的内容的 md5。它首先创建多部分实体,然后将其写入一个新文件,以便可以在该文件上制作 md5。

public class MyRestClient extends AsyncHttpClient {

 public void sendBackup(String secretKey, String accessId, AsyncHttpResponseHandler responseHandler){

    File file = new File(FileUtil.DATBASE_DIRECTORY_PATH + File.separator + FileUtil.DATABASE_FILE_NAME + ".db");
    MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, boundary, Charset.forName("UTF-8"));
    FileBody fileBody = new FileBody(file);
    entity.addPart("device_backup[database_dump]", fileBody);


    //creating this dummy file is crucial because for the server to authorize this file the
    //server takes the md5 of the raw_post of the request and compares it to the md5 in the header
    //this dummy file is mimicking the request.raw_post that is done on the server
    File dummyFile = new File(FileUtil.DATBASE_DIRECTORY_PATH + File.separator + "dummy.db");
    try {

      if (!dummyFile.exists()) {
        dummyFile.createNewFile();
      }

      FileOutputStream fileOutputStream = new FileOutputStream(dummyFile);
      entity.writeTo(fileOutputStream);

      fileOutputStream.flush();
      fileOutputStream.close();

    } catch (IOException e) {
      e.printStackTrace();
    }

    setAuth(DEVICE_BACKUP_EXTENSION, dummyFile, secretKey, accessId);

    super.post(MyApplication.getContext(), DEVICE_BACKUP_URL, entity, MultipartContentType, responseHandler);
  }
}

到目前为止我所拥有的:

public void backupCurrentDatabase(final Long backupId) {

    public static String boundary = "*****";
    public static final String MultipartContentType = "multipart/form-data;boundary=" + 
        boundary + "; charset=UTF-8";

    SharedPreferences prefs = getActivity().getSharedPreferences(Const.SHARE_PREF_NAME, Context.MODE_PRIVATE);
    String accessId = prefs.getString(Const.ACCESS_ID_PREF_KEY, null);
    String secretKey = prefs.getString(Const.SECRET_KEY_PREF_KEY, null);
    File file = new File(FileUtil.DATBASE_DIRECTORY_PATH + File.separator + FileUtil.DATABASE_FILE_NAME + ".db");

    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("device_backup[database_dump]", FileUtil.DATABASE_FILE_NAME + ".db",
                    RequestBody.create(MediaType.parse(MultipartContentType), file))
            .build();

    File dummyFile = new File(FileUtil.DATBASE_DIRECTORY_PATH + File.separator + "dummy.db");
    try {

      if (!dummyFile.exists()) {
        dummyFile.createNewFile();
      }

      FileOutputStream fileOutputStream = new FileOutputStream(dummyFile);
      //Write requestBody to dummyFile

      fileOutputStream.flush();
      fileOutputStream.close();

    } catch (IOException e) {
      e.printStackTrace();
    }

    SyncApi client = ServiceGenerator.createService(SyncApi.class, ServiceGenerator.DEVICE_BACKUP_EXTENSION,
            dummyFile, secretKey, accessId);
    Call<SendBackup> call = client.sendBackup(requestBody);
  }

因此,我获取相同的信息并制作一个可以通过 Retrofit 传递的 RequestBody。看来这应该是我写给 dummyFile 的内容。接下来是将 Multipart 写入 dummyFile 的相同代码,只是它缺少实际写入 fileOutputStream 的重要部分,因为我不知道要使用什么函数。接下来,设置 Retrofit 实例并将所有身份验证信息传递给我的服务生成器。最后拨打电话并将 requestBody 传递给 Retrofit。(未显示 call.enqueue() 的东西)

我缺少什么来完成这项工作?RequestBody 甚至是正确的使用方法吗?

4

1 回答 1

0
 /**
 * Upload picture API method.
 * This upload picture feature is only for demo purpose.
 */
public void UploadPictureToServer()
{
    if (file != null)
    {
        final APIParameters parameters = new APIParameters(MainActivity.this,true,false);
        Call<ResponseBody> call = parameters.GetUploadImageParameters(file);
        if (call == null)
        {
            return;
        }
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

                parameters.DismissLoader();
                GetUploadImageData(response);
            }

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

                parameters.DismissLoader();
                t.printStackTrace();
            }
        });
    }
}

/**
 * Get Upload image response for parsing data
 * @param response
 */
private void GetUploadImageData(Response<ResponseBody> response)
{
    String MyResult = null;
    try
    {
        MyResult = CM.GetAPIResponseStatus(response.body().string(),MainActivity.this);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }

    if (MyResult == null)
    {
        return;
    }

    ArrayList<Model_Category> model_categoryArrayList = JSONHelper.parseUploadImageResponse(MyResult);
    if (model_categoryArrayList != null)
    {
     /*   try
        {
            CacheMemory.writeObject(MainActivity.this, "category.txt", model_categoryArrayList);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }*/
        for (int i=0;i<model_categoryArrayList.size();i++)
        {
            Log.e("Category :-->","Id : "+model_categoryArrayList.get(i).id+" Name : "+model_categoryArrayList.get(i).categoryName);
        }
    }
}

API接口

/**
 * If you do not need any type-specific response, you can specify return value as simply Call<ResponseBody>.
 * @param image
 * @param //name
 * @return
 */
@Multipart
@POST(URLS.WEB_ADD_CATEGORY)
Call<ResponseBody> postImage(@Query(WebServicesTags.TAG_STR_APIKEY) String apiKey,@Part MultipartBody.Part image,@Part("userId") RequestBody userId,@Part("categoryName") RequestBody categoryName,@Part("deviceType") RequestBody deviceType,@Part("deviceToken") RequestBody deviceToken,@Part("accessToken") RequestBody accessToken,@Part("intUdId") RequestBody intUdId);
于 2016-12-24T06:26:18.297 回答