2013-08-06 2 views
0

Привет, я в первую очередь разработчик Android и довольно не разбираюсь в протоколах HTTP, вы очень цените!Android Http Post to REST Api

Я пытаюсь сделать ави зовут: http://api.haikutest.com/developer/apidoc/assignments.html, где я отправляю файл на устройство.

Они дают образец запрос о:

POST /api/assignments/3/submit 
message[subject]=Subject+of+the+message&message[body]=Some+long+text&message[sent_at]=2013-07-05&message[draft]=0&message[assignment_id]=3&files[][file]=%23%3CFile%3A0x007ff59c9c1de8%3E&files[][filename]=test.pdf 

И в описании состоянии, что файлы пары являются:

Массив файлов с каждым элементом, содержащим хэш файла и base64 закодирован файл

Это код, который я пытаюсь сейчас (примечание: я использую Robospice + Spring для Android):

File file = new File(Environment.getExternalStorageDirectory() + 
       "/DCIM/Camera/1357279228432.jpg"); 
     Base64InputStream stream = new Base64InputStream(new FileInputStream(file), 0); 
     HttpHeaders headers = new HttpHeaders(); 
     headers.add("x-haiku-auth", HaikuAPI.getAuthHeader()); 
     headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); 
     MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>(); 
     parts.add("files[][file]", parts); 
     HttpEntity<Object> request = new HttpEntity<Object>(stream, headers); 
     UriComponentsBuilder builder = UriComponentsBuilder 
       .fromUriString(
         "https://" + HaikuAPI.getDomain() + "/api/assignments") 
       .pathSegment(assignmentID + "", "submit") 
       .queryParam("message[subject]", "Assignment Completed") 

       .queryParam("message[body]", message) 
       .queryParam("message[assignment_id]", assignmentID) 
       .queryParam("files[][filename]", "test.jpg"); 

     URI url = builder.build().toUri(); 

     String response = getRestTemplate().postForObject(url, request, String.class); 
     return response; 

Но я получаю сообщение о том, что он не может сериализовать поток в JSON. Следуя документации API, я должен разместить поток как параметр? И каков правильный способ реализации этого? Мне бы очень понравилось, если бы мне не пришлось устанавливать ограничение на размер файла для пользователя, следовательно, потоки. Хотя я получил его для работы с небольшими файлами, закодированными в Base64 и размещенными непосредственно в качестве параметра ...

Любая помощь очень ценится! Я определенно не буду опускать комментарии или ответы для небольших указателей.

Обновлено

Обновленный код, но все равно получите еще одно сообщение об ошибке:

00:25:50.904 Thread-2066 An exception occurred during request network execution :Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [application/x-www-form-urlencoded] 
+1

Я не совсем уверен, но я сомневаюсь, что вы можете передавать файл снова, если служба ожидает, что вы просто отправить 1 полный запрос –

+0

@stefan запрос образца имеет слово файл в нем и крайне мало для PDF ... Как они это сделали? –

ответ

1

Похоже, что вы используете Spring for Android. Судя по тому, что сообщение об ошибке кажется, что Spring заставляет тип контента быть application/json, в то время как я считаю, что вы пытаетесь отправить application/x-www-form-urlencoded. Так установить этот Content-Type заголовок:

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); 

Spring будет знать то, чтобы соответствовать правильной MessageConverter. Подробнее об этом here.

EDIT: Кроме того, вы должны отправлять данные запроса в данные POST, а не в URI запроса. Переместите это на MultiValuesMap. Взгляните на ссылку, которую я дал вам, как публиковать такие данные. Полная документация по ним также может быть найдена here.

EDIT2 Для ответа также необходимо установить MessageConverter. Что-то вроде:

List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>(); 
acceptableMediaTypes.add(MediaType.APPLICATION_JSON); 
headers.setAccept(acceptableMediaTypes); 

EDIT3 Если вам нужно отправить файлы, рассмотреть возможность использования Resource, чтобы быть более конкретным InputStreamResource. Но есть трюк: вам нужно указать имя файла и размер файла, иначе ваш запрос будет сбой.Что-то вроде:

Resource res = new InputStreamResource(context.getContentResolver().openInputStream(itemImage)) { 
       @Override 
       public String getFilename() throws IllegalStateException { 
        return fileInfo.getFileName(); 
       } 

       @Override 
       public long contentLength() throws IOException { 
        return fileInfo.getFileSizeInBytes(); 
       } 
      }; 
+0

Спасибо, я попробую, когда я приду домой –

+0

Я пробовал это, но это не сработало ... Я обновил свой вопрос, чтобы отразить это. Что я делаю не так? –

+0

Все дело в том, чтобы найти соответствующий MessageConverter для того, что вы отправляете. Можете ли вы попробовать 'headers.setContentType (MediaType.TEXT_PLAIN);'? – gunar

 Смежные вопросы

  • Нет связанных вопросов^_^