Android中的PATCH动词(OkHttp,Volley,Retrofit ...)

时间:2015-01-27 01:43:46

标签: android android-volley okhttp

我知道现在已经问了几次类似的问题,但我似乎找不到解决一个简单问题的方法:PATCH动词。

所以我问任何通过使用OkHttp,Volley或Retrofit解决Android中的PATCH问题的人(或者如果您使用不同的方法或库,请分享)。

我花了3天时间挖掘,我无法找到解决这个问题的方法。我所要做的就是通过在.NET环境中构建和运行的RESTful API对表进行部分更新。

我目前正在使用Volley,但是每次运行应用程序时,都会收到异常错误,该错误会显示PATCH is not an allowed...?行的内容,然后会提供一系列可以使用的其他动词,例如& #34; POST,PUT,GET ......"。所以,根本没有帮助。

我尝试过这样使用OkHttp

  JSONObject infoRequestBody = new JSONObject();


    try {


        infoRequestBody.put("Salutation", "MRrr.");
        infoRequestBody.put("FirstName", "Work Now!!");
        infoRequestBody.put("LastName", "Test from my mobile again!! Okhttp");
        infoRequestBody.put("MiddleName", "From the Mobile");
        infoRequestBody.put("NickName", null);
        infoRequestBody.put("BirthDate", "1978-11-23T00:00:00.000Z");
        infoRequestBody.put("CompanyName", null);
        // infoRequestBody.put("RegDate", "2015-01-18T23:39:13.873Z");
        infoRequestBody.put("Gender", "Male");
        infoRequestBody.put("IsPregnant", null);
        infoRequestBody.put("IsNursing", null);
        infoRequestBody.put("WorkPhone", null);
        infoRequestBody.put("WorkPhoneExt", null);
        infoRequestBody.put("PhoneNumber", null);
        infoRequestBody.put("Address", "My android app working!!");
        infoRequestBody.put("Address2", null);
        infoRequestBody.put("City", null);
        infoRequestBody.put("State", "CA");
        infoRequestBody.put("ZipCode", null);
        infoRequestBody.put("EmailAddress", "email@me.com");
        infoRequestBody.put("Occupation", null);
        infoRequestBody.put("CountryofResidence", "United States");
        infoRequestBody.put("CountryCode", "US");
        infoRequestBody.put("Ethnicity", "Asian");
        infoRequestBody.put("ModifiedDate", "2015-01-18T23:39:13.873Z");
        infoRequestBody.put("ModifiedBy", null);
        infoRequestBody.put("AcceptedTerms", true);
        infoRequestBody.put("AcceptedPrivacyPolicyCheckbox", false);
        infoRequestBody.put("AcceptedUnder18ConsentCheckbox", false);
    } catch (JSONException e1) {
        e1.printStackTrace();
    }
  RequestBody body = com.squareup.okhttp.RequestBody.create(JSON, infoRequestBody.toString());


    com.squareup.okhttp.Request.Builder request = new com.squareup.okhttp.Request.Builder()
             .url("APIUrls.PATIENT_INFO_URL")
            .addHeader("Content-Type", "application/json")
            .addHeader("Accept", "application/json")
            .addHeader("X-ZUMO-APPLICATION", APIUrls.ZUMO_KEY)
            .patch(body);



    client.newCall(request).enqueue(new Callback() {




        @Override
        public void onFailure(com.squareup.okhttp.Request request, IOException e) {


        }

        @Override
        public void onResponse(com.squareup.okhttp.Response response) throws IOException {

            if (!response.isSuccessful()) throw new IOException("Unexpected code" + response);

            Headers responseHeaders = response.headers();
            for (int i = 0; i < responseHeaders.size(); i++) {
                System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
            }


            System.out.println(response.body().string());

        }
    });

client.newCall(request).enque(new Callback()...错误地指出request无法应用于Request.Builder

顺便说一句,我是OkHttp的新手。

无论如何,我一直在努力让PATCH长时间工作。也许我在黑暗中拍摄,但如果有任何人有任何建议,想法如何让'PATCH`工作,我将永远感激你。

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

正如GreyBeardedGeek所说,您可以使用Retrofit + OkHttp来实现此目标。

RestAdapter restAdapter = new RestAdapter.Builder()
                .setClient(new OkClient())
                .setEndpoint(ENDPOINT)
                .build();
MyPatchService patchService = restAdapter.create(MyPatchService.class);
UserUpdate updatedUser = new UserUpdate();
updatedUser.Salutation = "Mr";
updatedUser.FirstName = "Adam";
patchService.update(updatedUser);

MyPatchService看起来像这样:

public interface MyPatchService {
    @PATCH("/some/update/endpoint")
    User update(UserUpdate updatedObject);
}

您的UserUpdate课程可能如下所示:

public class UserUpdate {
    public String Salutation;
    public String FirstName;
    public String LastName;
}

如果这样做,将要发送的JSON将如下所示(请注意LastName未被序列化,因为它从未设置过 - 这可以通过向Retrofit提供自定义Gson实例来配置):

{
  "Salutation": "Mr",
  "FirstName": "Adam"
}

请求/响应对象是您通过网络发送/接收的对象的纯Java表示形式。作为补丁请求,您可以将您的会员变成IntegerBoolean等,如果没有设置,它们将不会被序列化(即如果它们是null)。

答案 1 :(得分:1)

我没试过这个,但显然,如果你使用OkHTTP的OKClient进行Retrofit,那么Retrofit支持@Patch注释。

请参阅http://square.github.io/retrofit/javadoc/retrofit/http/PATCH.htmlRetrofit & HTTP Patch

答案 2 :(得分:1)

好的!感谢@Adam和所有帮助我实现正确方向的人。真的很感激。所以,这就是我最终做的事情(我几乎没有定制@Adam发布的内容,当然这是正确答案!):

首先,

我按如下方式设置了我的UserUpdate课程:

public class UserUpdate {
public String Salutation;
public String FirstName;
public String LastName;
public String MiddleName;
public String NickName;

     //Setters and Getters...
  public String getSalutation() {
      return Salutation;
  }

  public void setSalutation(String salutation) {
      Salutation = salutation;
  }

  public String getFirstName() {
     return FirstName;
  }

  public void setFirstName(String firstName) {
     FirstName = firstName;
  }

  public String getLastName() {
      return LastName;
  }

  public void setLastName(String lastName) {
      LastName = lastName;
  }

public String getMiddleName() {
    return MiddleName;
}

public void setMiddleName(String middleName) {
    MiddleName = middleName;
}

public String getNickName() {
    return NickName;
}

 public void setNickName(String nickName) {
     NickName = nickName;
 }


}

然后我设置了名为interface class的{​​{1}}:

PatientInfoAPI

注意我将表id传递给“PATCH'd”,最重要的是我有public interface PatientInfoAPI{ @PATCH("/tables/PatientInformation/{id}") public void update(@Body UserUpdate updatedDAta, @Path("id") String id,Callback<UserUpdate> response); } 注释,它允许我将数据传递给更新而不会出错(我试过没有它)并且收到错误)

最后在我的主要活动中:

@Body

我知道也许有些步骤不是很复杂,但对于那些从Retrofit和OkHttp开始的人来说,最重要的是一直在努力让 RestAdapter restAdapter = new RestAdapter.Builder() .setClient(new OkClient()) //very important!!! .setEndpoint(ENDPOINT)//base url .setRequestInterceptor(new RequestInterceptor() {//You may not need to pass headers, but I do, so this is how it's done. @Override public void intercept(RequestFacade request) { request.addHeader("Content-Type", "application/json"); request.addHeader("Accept", "application/json"); request.addHeader("X-ZUMO-APPLICATION", APIUrls.ZUMO_KEY); } }) .build(); PatientInfoAPI patchService = restAdapter.create(PatientInfoAPI.class); UserUpdate updatedUser = new UserUpdate(); updatedUser.setSalutation("Sr."); updatedUser.setFirstName("YesSirtItsWorking"); updatedUser.setLastName("Bays"); updatedUser.setMiddleName("ComeOn Now man!"); updatedUser.setNickName(""); //Passing the tableId along with the data to update patchService.update(updatedUser, APIUrls.TABLE_ID, new retrofit.Callback<UserUpdate>() { @Override public void success(UserUpdate userUpdates, retrofit.client.Response response) { Log.v("All is good", "Nickname:" + userUpdates.getNickName().toString() + " Email: " + userUpdates.getEmailAddress().toString()); } @Override public void failure(RetrofitError error) { Log.v("All is good", error.getLocalizedMessage().toString()); } }); 与Android合作,这就是解决方案。再次,@Adam的道具几乎指导我完成整个过程。 @Adam是真正回答这个问题的人 - 我只是把它们放在一起,供那些可能需要看到全貌的人们使用。谢谢,@ Adam!你是一个摇滚明星!