我有一个调用.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());
解码String的结果。而且,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>
希望它有所帮助!享受。
答案 0 :(得分:3)
我认为您正在构建和保存的字符串仍然在base64中,这就是它无法打开的原因。
在这种情况下,您也不希望将StringBuilder用于整个内容,因为大型PDF将耗尽您的进程的所有内存。
当您从pull解析器获取元素内容的字符时,请动态执行base64转换并将转换后的字节写入输出文件。
答案 1 :(得分:0)
错误应该在文件路径中。试试这个:
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + File.Separator + filename);