Отправить пару имя/значение как объект в Multipart с помощью Retrofit

В моем коде я должен сделать запрос PUT MultipartForm-Data для обновления объекта на сервере, он должен быть Multipart, поскольку возможно, что пользователь отправит изображение вместе с данными.

Для этого я в настоящее время использую Retrofit, поскольку это библиотека, к которой я прилично привык, и она работает для отправки изображений на сервер.

Однако на стороне сервера все изменилось, и теперь одним из параметров, который необходимо отправить, является:

{"step":
    {"type":"begin"}
}

Однако это оказалось на удивление трудно сделать.

Вещи, которые я пробовал, включают передачу его как MultipartTypedOutput, набранную вручную строку и JSONObject, преобразованный в строку, и все это дало мне:

retrofit.RetrofitError: 400 Неверный запрос

Используемый URL-адрес правильный, я дважды проверил с человеком, который обслуживает сервер, и он достигает сервера, но с неправильным объектом «шаг».

Я также пытался передать его как NameValuePair, Map и HashMap, и все это дало мне:

retrofit.RetrofitError: Тело детали не должно быть нулевым.

@FieldPart, который выглядит идеально для этого, не совместим с Multipart, так есть ли вообще способ сделать это с помощью Retrofit?

Мой текущий метод PUT таков:

@Headers({
    "Connection: Keep-Alive",
    "Accept-Language: en-US"
})
@Multipart
@PUT("/0.1/user/{id}")
String updateUser(@Path("id") String userId, @Part("step") Map<String,String> type);

Где тип карты был изменен на все типы, о которых я упоминал ранее.


person Larpus    schedule 28.01.2016    source источник
comment
Пожалуйста, добавьте код, который вы сейчас используете, а также ответ на HTTP-запросы.   -  person Code-Apprentice    schedule 28.01.2016
comment
Извините, после переписывания вопроса пару раз забыли повторно добавить фактический код. Вопрос был отредактирован, чтобы исправить это.   -  person Larpus    schedule 28.01.2016
comment
@Larpus, если приведенный ниже ответ послужил вашей цели, рассмотрите возможность ответа и закройте его.   -  person Ankush Sharma    schedule 29.01.2016


Ответы (2)


Вы на самом деле делаете это правильно, просто нужно быстро исправить. У меня есть два предложения для вас: 1. Вы можете создать такой внутренний класс

public class Example {

@SerializedName("type")
@Expose
private String type;

/**
* 
* @return
* The type
*/
public String getType() {
return type;
}

/**
* 
* @param type
* The type
*/
public void setType(String type) {
this.type = type;
}

}

В этом случае ваш API будет выглядеть так

@Multipart
@PUT("/0.1/user/{id}")
String updateUser(@Path("id") String userId, @Part("step") Example exp);
  1. или вы можете использовать JsonObject, это не Apache JSONObject, который вы уже использовали. Это объект google gson, который входит в пакет com.google.gson. Здесь вам нужно сделать следующее: JsonObject settingObject = new JsonObject(); SettingObject.addProperty ("тип", "начало"); В этом случае будет,

    String updateUser(@Path("id") String userId, @Part("step") JsonObject obj);

Это все, что вам нужно, кстати, вы также можете установить заголовок раз и навсегда, зачем определять его через API?

person Ankush Sharma    schedule 28.01.2016
comment
Прошу прощения, что так долго, другие части проекта требовали немедленного внимания. Как оказалось, по какой-то причине оба метода по-прежнему выдавали мне ошибку Part body not be null, но мне удалось решить ее другим способом. - person Larpus; 02.02.2016

Я до сих пор не понимаю, в чем проблема, так как «тело части не должно быть нулевым» возникало даже при попытке того, что упомянул Анкуш.

В любом случае, я поговорил с несколькими друзьями и через несколько расширений контактов я получил следующее решение:

@Headers({
    "Connection: Keep-Alive",
    "Accept-Language: en-US"
})
@Multipart
@PUT("/0.1/user/{id}")
String updateUser(@Path("id") String userId, @Part("step[type]") String type);

Насколько я мог найти, это нигде не упоминается в документации по модернизации, но это работает.

person Larpus    schedule 02.02.2016