2010-06-21 2 views
0

EDIT:Использование Android для отправки файлов XML

Я пытаюсь отправить XML-файл в качестве почтового запроса в Android.

Сервер принимает текст/xml. Я попытался создать MultipartEntity, который имеет тип контента multipart/form-data.

HttpClient httpClient = new DefaultHttpClient(); 

    /* New Post Request */ 
    HttpPost postRequest = new HttpPost(url); 

    byte[] data = IOUtils.toByteArray(payload); 

    /* Body of the Request */ 
    InputStreamBody isb = new InputStreamBody(new ByteArrayInputStream(data), "uploadedFile"); 
    MultipartEntity multipartContent = new MultipartEntity(); 
    multipartContent.addPart("uploadedFile", isb); 

    /* Set the Body of the Request */ 
    postRequest.setEntity(multipartContent); 

    /* Set Authorization Header */ 
    postRequest.setHeader("Authorization", authHeader); 
    HttpResponse response = httpClient.execute(postRequest); 
    InputStream content = response.getEntity().getContent(); 
    return content; 

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

The server refused this request because the request entity is in a format not supported by the requested resource for the requested method (Cannot consume content type). 

Как изменить тип содержимого запроса?

Edit:

+0

Что вы хотите изменить? Что теперь и почему сервер не поддерживает его? –

+1

Если вы отправляете xml, есть ли какая-то конкретная причина, по которой вы используете MultipartEntity? –

+0

@Lauri. Я думал, что тоже отправлю StringBody. Есть ли более простой способ отправки XML-файла? – unj2

ответ

3

Short story short - используйте другой конструктор для InputStreamBody, который позволяет указать тип mime, который вы хотите использовать. Если вы этого не сделаете, детали в вашем многостраничном запросе не будут указаны как указано Content-Type (подробнее см. Ниже). Следовательно, сервер не знает, какой тип файла есть, и в вашем случае может отказаться от его принятия (мой принял их в любом случае, но я предполагаю, что это обусловлено конфигурацией). Если это все еще не работает, может возникнуть проблема с сервером.

Примечание: изменение Content-Type самого запроса на что-либо, кроме multipart/form-data; boundary=someBoundary, делает запрос недействительным; сервер не будет правильно разбирать многочастные части.

Длинные истории - вот мои выводы.

Учитывая следующий код:

byte[] data = "<someXml />".getBytes(); 
multipartContent.addPart("uploadedFile", new InputStreamBody(new ByteArrayInputStream(data), "text/xml", "somefile.xml")); 
multipartContent.addPart("otherPart", new StringBody("bar", "text/plain", Charset.forName("UTF-8"))); 
multipartContent.addPart("foo", new FileBody(new File("c:\\foo.txt"), "text/plain")); 

на посты HTTPClient следующую полезную нагрузку (захваченное ж/Wireshark):

POST /upload.php HTTP/1.1 
Transfer-Encoding: chunked 
Content-Type: multipart/form-data; boundary=SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3 
Host: thehost.com 
Connection: Keep-Alive 
User-Agent: Apache-HttpClient/4.1-alpha2 (java 1.5) 

--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3 
Content-Disposition: form-data; name="uploadedFile"; filename="someXml.xml" 
Content-Type: text/xml 
Content-Transfer-Encoding: binary 

<someXml /> 
--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3 
Content-Disposition: form-data; name="otherPart" 
Content-Type: text/plain; charset=UTF-8 
Content-Transfer-Encoding: 8bit 

yo 
--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3 
Content-Disposition: form-data; name="foo"; filename="foo.txt" 
Content-Type: text/plain 
Content-Transfer-Encoding: binary 

Contents of foo.txt 

--SeXc6P2_uEGZz9jJG95v2FnK5a8ozU8KfbFYw3-- 

На сервере, следующий скрипт:

<?php 
print_r($_FILES); 
print_r($_REQUEST); 

выплюнуло следующее:

Array 
(
    [uploadedFile] => Array 
     (
      [name] => someXml.xml 
      [type] => text/xml 
      [tmp_name] => /tmp/php_uploads/phphONLo3 
      [error] => 0 
      [size] => 11 
     ) 

    [foo] => Array 
     (
      [name] => foo.txt 
      [type] => text/plain 
      [tmp_name] => /tmp/php_uploads/php58DEpA 
      [error] => 0 
      [size] => 21 
     ) 

) 
Array 
(
    [otherPart] => yo 
) 
+0

Nah. Не повезло. Сервер по-прежнему отклоняет мой ввод. Есть ли способ отправить XML-контент, не делая его многопроцессорным? – unj2

+0

XML - это простой текст, вы можете использовать StringEntity вместо MultipartEntity. Хотите попробовать указать код Android на http://systemout.com/upload.php и проверить, что он выводит (это страница, с которой я тестировался)? –

+0

Hi Lauri. Большое вам спасибо за то, что помогли мне. Иногда я удивляюсь силе Интернета. В любом случае я могу только поддержать вас и дать вам несколько моментов. Но String Entity работал как шарм. Еще раз спасибо. Хотел бы я сделать больше, чтобы выразить свою благодарность. :) – unj2

-1

Использование кода должно работать:

response.setContentType("Your MIME type"); 
+0

Мне нужно изменить тип содержимого запроса. – unj2

-1

Независимо от API, тип контента согласовывается с заголовком с 'Content-Type' ключ:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Вы не можете контролировать то, что ожидает служба. Это часть их контракта. Вероятно, вы отправляете «text/plain», и они ожидают чего-то в области «multipart/form-data» (думаю, данные html-формы).

+0

Я думаю, что http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html более применим в этом случае, multipart-запросы могут указывать более одного Content-Type. Я также думаю, что HttpClient обнаруживает и устанавливает правильный для прикрепленного файла. –

+0

Но здесь ... Я отправлю его вам: http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/methods/PostMethod.html вызов setParameter («Содержимое -Type "," theexpected/type ") – Droo

0

вы можете пойти по этому пути для загрузки на сервер

 HttpClient httpclient = new DefaultHttpClient(); 
     HttpPost httppost = new HttpPost(url); 
     InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(filePath), -1); 
     reqEntity.setContentType("binary/octet-stream"); 
     reqEntity.setChunked(true); // Send in multiple parts if needed 
     httppost.setEntity(reqEntity); 
     HttpResponse response = httpclient.execute(httppost); 
0

я сделал что-то подобное для доступа к веб-сервисы. Мыльный запрос был запросом XML.См. Код ниже:

package abc.def.ghi; 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.ResponseHandler; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.StringEntity; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.params.HttpConnectionParams; 
import org.apache.http.params.HttpParams; 
import org.apache.http.params.HttpProtocolParams; 
import org.apache.http.util.EntityUtils; 


public class WebServiceRequestHandler { 

    public static final int CONNECTION_TIMEOUT=10000; 
    public static final int SOCKET_TIMEOUT=15000; 

    public String callPostWebService(String url, String soapAction, String envelope) throws Exception { 
     final DefaultHttpClient httpClient=new DefaultHttpClient(); 
     HttpParams params = httpClient.getParams(); 
     HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT); 
     HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT); 

     HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true); 

     // POST 
     HttpPost httppost = new HttpPost(url); 
     // add headers. set content type as XML 
     httppost.setHeader("soapaction", soapAction); 
     httppost.setHeader("Content-Type", "text/xml; charset=utf-8"); 

     String responseString=null; 
     try { 
      // the entity holds the request 
      HttpEntity entity = new StringEntity(envelope); 
      httppost.setEntity(entity); 

      ResponseHandler<String> rh=new ResponseHandler<String>() { 
       // invoked on response 
       public String handleResponse(HttpResponse response) 
       throws ClientProtocolException, IOException { 
        HttpEntity entity = response.getEntity(); 

        StringBuffer out = new StringBuffer(); 
            // read the response as byte array 
        byte[] b = EntityUtils.toByteArray(entity); 
        // write the response byte array to a string buffer 
        out.append(new String(b, 0, b.length));   
        return out.toString(); 
       } 
      }; 
      responseString=httpClient.execute(httppost, rh); 
     } 
     catch (UnsupportedEncodingException uee) { 
      throw new Exception(uee); 

     }catch (ClientProtocolException cpe){ 

      throw new Exception(cpe); 
     }catch (IOException ioe){ 
      throw new Exception(ioe); 

     }finally{ 
      // close the connection 
      httpClient.getConnectionManager().shutdown(); 
     } 
     return responseString; 
    } 

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