android - 从 Android 的 .NET WebService 中保存字节

标签 android .net ksoap2

我有一个调用 .NET WebService 的 Android 应用程序,它发回一个 base64 二进制编码字节(它是一个 PDF 文件)。

我的目标是将这些字节作为 PDF 文件保存在设备的 SD 卡上。

这是(一小部分)我从 WebService 得到的响应:

<base64Binary xmlns="https://www.abcd.com">JVBERi0xLjMKJdP0zOEKM....</base64Binary>

在我的应用程序端,我使用 POST(用于身份验证目的)请求调用此 WebService。然后我得到结果并用 XmlPullParser 解析它。节点值(字节)存储在 StringBuilder 中(这是一个不错的选择吗?),我这样保存文件:

try
{
    FileOutputStream fos = new FileOutputStream(path + "/" + filename);
    fos.write(nodeValue.toString().getBytes());
    fos.close();
}
catch(FileNotFoundException ex)
{
    System.out.println("FileNotFoundException : " + ex);
}
catch(IOException ioe)
{
    System.out.println("IOException : " + ioe);
    response = false;
}

当我使用 DDMS 提取创建的 PDF 文件并尝试使用 Acrobat Reader 打开它时,我收到一个错误消息,指出该文件的格式不正确。

有什么想法吗?

======= 答案 =======

为了解决我的问题,我使用了 kSoap2库以从 WebService 获取结果作为 SOAP 响应。以下是它是如何做到这一点的。

private static final String SOAP_ACTION = "https://www.foobar.com/getFile";
private static final String METHOD_NAME = "getFile";
private static final String NAMESPACE = "https://www.foobar.com";
private static final String URL = "http://www.foobar.com/ws.asmx";

try
{
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty("username", "foo");
    request.addProperty("password", "bar");
    request.addProperty("file", "foo.pdf");

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.setOutputSoapObject(request);
    envelope.dotNet = true;

    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    androidHttpTransport.call(SOAP_ACTION, envelope);

    // Get the result
    SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
    byte[] result = Base64.decode(resultsRequestSOAP.getProperty("getFileResult").toString());

    // Save the file
    try
    {
        FileOutputStream fos = new FileOutputStream("/mnt/sdcard/documents/foo.pdf");
        fos.write(result);
        fos.close();
    }
    catch(FileNotFoundException ex)
    {
        System.out.println("FileNotFoundException : " + ex);
    }
    catch(IOException ioe)
    {
        System.out.println("IOException : " + ioe);
    }
}
catch (Exception e)
{
    e.printStackTrace();
}

行:

byte[] result = Base64.decode(resultsRequestSOAP.getProperty("result").toString());

解码字符串的结果。并且,byte[] 数组保存在一个文件中:

fos.write(result);

瞧!这是为遇到相同问题的人提供的完整代码。这是我调用的 WebService 签名:

POST /wsInspection.asmx HTTP/1.1
Host: www.foobar.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "https://www.foobar.com/getFile"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <getFile xmlns="https://www.foobar.com">
    <username>string</username>
    <password>string</password>
    <file>string</file>
</getFile>
</soap:Body>

响应:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <getFileResponse xmlns="https://www.foobar.com">
        <getFileResult>base64Binary</getFileResult>
    </getFileResponse>
    </soap:Body>
</soap:Envelope>

希望对您有所帮助!享受吧。

最佳答案

我认为您正在构建和保存的字符串仍在 base64 中,这就是它无法打开的原因。

在这种情况下,您也不希望对整个内容使用 StringBuilder,因为大型 PDF 会耗尽您的进程的所有内存。

当您从拉式解析器获取元素内容的字符时,即时进行 base64 转换并将转换后的字节写入输出文件。

关于android - 从 Android 的 .NET WebService 中保存字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8536219/

相关文章:

c# - WCF 托管和性能

.net - scala.net 生产准备好了吗?

java - Android 上使用 ksoap2 进行双倍操作?

Android:如何存储 cookie?

c# - 使用 C# 将多个音频样本混合到单个文件中

java - 从 Android 中的 AlertDialog 返回信息

android - 在 ksoap2 android 中找不到类型错误的解串器

java - Android中的Ksoap2无法序列化

android - 如何在 android 2.2 模拟器或 android 2.1 设备中使用地理编码器

android - Zygote 共享库处理