【问题标题】:Using Android to Post XML files使用 Android 发布 XML 文件
【发布时间】:2010-06-21 23:05:59
【问题描述】:

编辑:

我正在尝试在 Android 中将 xml 文件作为 post 请求发送。

服务器接受文本/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).

如何更改请求的内容类型?

编辑:

【问题讨论】:

  • 你想把它改成什么?现在是什么,为什么服务器不支持?
  • 如果您发送 xml,您使用 MultipartEntity 是否有某些特定原因?
  • @Lauri。我想我也会发送一个 StringBody 。有没有更简单的方法只发送 XML 文件?
  • 您希望服务器接收 XML 文件还是只接收 XML 内容?
  • 告诉编写服务器的人,他们应该使用PUT,而不是POST,来提交text/xml 内容。

标签: java android apache httpclient http-post


【解决方案1】:

长话短说 - 为您的 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 脚本:

<?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
)

【讨论】:

  • 不。没有运气。服务器仍然拒绝我的输入。有没有办法我可以发送 XML 内容而无需将其设为多部分?
  • XML 是纯文本,您可以使用 StringEntity 而不是 MultipartEntity。想尝试将您的 Android 代码指向 systemout.com/upload.php 并查看它的输出(这是我测试过的页面)吗?
  • 嗨劳里。非常感谢你帮助我。有时我想知道互联网的力量。无论如何,我只能投票给你并给你一些分数。但是字符串实体就像一个魅力。再次感谢你。希望我能做更多的事情来表达我的感激之情。 :)
  • @Foysal upload.php 只包含答案中显示的 PHP 代码(两个 print_r 语句)
  • 这是错字还是错误?你写了这个有效载荷:name="uploadedFile"; filename="text/xml" Content-Type: someXml.xml,但这个输出:[name] =&gt; someXml.xml [type] =&gt; text/xml
【解决方案2】:

你可以这样上传到服务器

        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);

【讨论】:

    【解决方案3】:

    我做了类似访问网络服务的事情。 soap 请求是一个 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;
        }
    
    }
    

    【讨论】:

      【解决方案4】:

      使用您的代码,以下应该可以工作:

      response.setContentType("Your MIME type");
      

      【讨论】:

      • 我需要更改请求的内容类型。
      【解决方案5】:

      无论 API 是什么,内容类型都是通过带有“Content-Type”键的标头协商的:

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

      您无法控制服务的预期。这是他们合同的一部分。您可能正在发送“text/plain”,而他们期待“multipart/form-data”领域的某些内容(想想 html 表单数据)。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多