java - 将 Base64 字符串从 xml 文件复制到文本文件时出现问题

标签 java xml jaxb base64 marshalling

我有一个 xml 文件,其中包含一个包含 base64 字符串的标签,如下所示:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <PercezioniEStorni>
           <MsgPercezioniStorni>  
               <ApplicazioneChiamante>PEI</ApplicazioneChiamante> 
               <DataElaborazione>31/03/2016</DataElaborazione> 
               <CodiceSede>3700203</CodiceSede> 
               <Esercizio>2015</Esercizio>
               <Trimestre>4</Trimestre>
               <PeriodoDal>01/10/2015</PeriodoDal>
               <PeriodoAl>31/12/2015</PeriodoAl>
               <DataValidazione>31/03/2016</DataValidazione>             
               <UtenteValidatore>giuseppe</UtenteValidatore>
               <CodFiscFirmatario>VGRGPP79E08E919T</CodFiscFirmatario>  
               <PercezioniEStorniTypeZip>          
                   <!-- Base64 example String -->
                   VUVzREJCUUFDQUFJQUNOcWYwZ0FBQUFBQUFBQUFBQUFBQUFaQUFBQWNtVm5hWE4wY204dE1Ua3lMVEl3TVRZeE1TMHhMbmh0Yk96ZGE1UGt4blh1KzYrUzRUZDh4   V0YzOWQzQm80aFZCVlFqdTNBWkpnRHlWTDFqeUF5WkVUS3BFR2w3Ny9QcFQ2Sm1lTEZrdTFkM3I4UWdoWC9FRG0xcWhxWmt6eTlYTCtTVEsvUExuMzc4OWkvZi9mQWYvMX    rOEIvZi9mbkh2M3puL3MrLy9mbUhuLzc1NHkvL1AvLzByei8vL0pkLy91S0xuLzc0cjkvOTI3Yy92WXUvTy8zV3V4Ly8rcWN2cHIvNDRydVAvM05mL05QSC84bi84OU8vL1BvLzlaLy8rWi92L3ZQcS9=
               </PercezioniEStorniTypeZip>
           </MsgPercezioniStorni>
       </PercezioniEStorni>
    </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

Base64字符串编码一个zip文件(只是一个例子,并不真正包含zip文件,真正的字符串太长)。 我通过 JAXB 生成的类以这种方式创建了此 xml:

    FileInputStream zipFis = new FileInputStream(fileZip);
    buffer = new byte[(new Long(fileZip.length())).intValue()];
    zipFis.read(buffer);
    zipFis.close();
    String encoded = Base64.encode(buffer);

    PercezioniEStorni percezioniStorni = new PercezioniEStorni();
    /** ...set other properties... **/
    MsgPercezioniStorni msgPercezioniStorni = new MsgPercezioniStorni();
    /** ...set other properties... **/
    msgPercezioniStorni.setPercezioniEStorniTypeZip(encoded.getBytes());
    percezioniStorni.setMsgPercezioniStorni(msgPercezioniStorni);

    JAXBContext jaxbContext = JAXBContext.newInstance(PercezioniEStorni.class,percezioniStorni);
    Marshaller marshaller = jaxbContext.createMarshaller();
    Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    marshaller.marshal(element, document);
    MessageFactory mf = MessageFactory.newInstance();
    SOAPMessage message = mf.createMessage();
    message.getSOAPBody().addDocument(document);

    File fileXml = new File(xmlPath);
    file.createNewFile();
    FileOutputStream fileOutput = new FileOutputStream(fileXml);
    message.writeTo(fileOutput);
    fileOutput.close(); 

然后我反转了这个过程:

    File file = new File(xmlPath);
    FileInputStream fis = new FileInputStream(file);
    BufferedReader br = new BufferedReader(new InputStreamReader(fis,"UTF-8"));
    String xml = "";
    while(br.ready()){
        xml += br.readLine();
    }
    br.close();

    MessageFactory mf = MessageFactory.newInstance();
    SOAPMessage message = mf.createMessage();
    SOAPPart soapPart = message.getSOAPPart();

    InputSource is = new InputSource();
    is.setByteStream(new ByteArrayInputStream(xml.getBytes("UTF-8")));

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    dbFactory.setNamespaceAware(true);
    DocumentBuilder builder = dbFactory.newDocumentBuilder();
    Document document = builder.parse(is);
    DOMSource domSource = new DOMSource(document);

    soapPart.setContent(domSource);
    message.saveChanges();
    PercezioniEStorni perc = SOAPUtil.unmarshal(PercezioniEStorni.class,message);
    byte[] decoded = Base64.decode(new String(perc.getMsgPercezioniStorni().getPercezioniEStorniTypeZip()));
    File zipFile = new File(zipPath);
    zipFile.createNewFile();
    FileOutputStream out = new FileOutputStream(zipFile);
    out.write(decoded);
    out.close();

一切正常。存档已成功解码,我可以解压它。

后来我手动将 xml 文件中的 Base64 字符串复制到另一个文本文件中。 我以这种方式从java读取这个文件:

    File txtFile = new File(textFilePath);
    FileInputStream fis = new FileInputStream(txtFile);
    Reader r = new InputStreamReader(fis,"UTF-8");
    StringBuilder sb = new StringBuilder();
    int buffer = 0;
    while ((buffer= r.read())!=-1) {
        sb.append((char)buffer);
    }
    fis.close();
    File zipFile = new File(zipPath);
    zipFile.createNewFile();
    FileOutputStream out = new FileOutputStream(zipFile);
    Base64.decode(sb.toString(),out);
    out.close();

这次 zip 存档已损坏。而且大小也不一样。 为什么?有没有办法从另一个文件读取相同的 Base64 字符串?

最佳答案

除非我忽略了一些事情:您正在手动编码从 zip 文件读取的一些数据:

String encoded = Base64.encode(buffer);

然后设置一个属性,该属性定义为以 Base64 存储字节数组,以避免任何违反 XML 规则的情况:

msgPercezioniStorni.setPercezioniEStorniTypeZip(encoded.getBytes());

现在,编码字符串encoded的字节再次被编码。

难怪 XML 中的字符无法通过单个解码步骤变成有效的 zip。 (尝试两个。)

更好:放弃第一个编码步骤。

关于java - 将 Base64 字符串从 xml 文件复制到文本文件时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36356491/

相关文章:

java - 向上转换为对象的 ArrayList 然后向下转换为自定义 ArrayList 的成本

java - 安装错误 : INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID

jaxb - 使用 XmlElementWrapper 时编码集合

jaxb - 输出空元素

Java:字节流中的 While 循环

java - 设置SeekBar的宽度使 "swipe to unlock"效果

Java:将 StreamResult 转换为 DOM

java - 在不更改模式的情况下更改类

java - 如何从不同的目录运行 java 程序?

java - 在 Android 的内部存储中保存文件