XML与Base64编码字符串转PDF

问题描述 投票:0回答:1

我有一个XML,其中我得到一个PDF文档作为一个Base64编码的字符串。

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
   <ns0:Message1>
      <ns1:Record xmlns:ns1="urn:test.com:pdf">
         <Field>**Contains the base 64 encoded string of the actual PDF**</Field>
      </ns1:Record>
   </ns0:Message1>
</ns0:Messages>

我试着在下面进行转换。我试着把XML内容作为输入并执行Base64转换。

public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException {
        try {
            InputStream inputstream = transformationInput.getInputPayload().getInputStream();
            OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream();
            // Copy Input content to Output content
            byte[] b = new byte[inputstream.available()];
            inputstream.read(b);

                    Base64.Decoder dec = Base64.getDecoder();
                byte[] decbytes = dec.decode(b);

           outputstream.write(decbytes);
        } catch (Exception e) {
        }
    }

我使用的工具不需要main,代码在运行时执行。但它不工作。我也试过删除XML标签。而且我还在工具的导入部分单独导入了java.util.Base64。任何帮助将是感激的。

java xml java-8 base64 decode
1个回答
0
投票

InputStream.available()的文档:

使用本方法的返回值来分配一个缓冲区以保存这个流中的所有数据是绝对不正确的。

当从InputStream读取数据时,你必须使用循环。 而且当你调用InputStream.read时,使用返回值是至关重要的,因为不能保证你的字节数组会被填满。

你还需要记住关闭你的流。 如果你不这样做,你会造成内存泄漏,一些数据可能不会被写入到OutputStream中。

Base64.Decoder有一个有用的方法。wrap(InputStream)它让你把解码当作普通的InputStream。

最后,请注意 永远不要写一个空的 catch 块,如果你不确定如何处理一个异常,那么不要 如果你不确定如何处理异常,那就不要删除trycatch,可以在其中添加 throws IOException 到你的方法的签名中,并让更高层次的应用程序决定最佳的行动方案(比如向最终用户显示错误信息)。

所以,你会想要这样的东西。

public void transform(TransformationInput transformationInput,
                      TransformationOutput transformationOutput)
throws StreamTransformationException,
       IOException {

    try (InputStream inputstream = Base64.getDecoder().wrap(
            transformationInput.getInputPayload().getInputStream());
        OutputStream outputstream =
            transformationOutput.getOutputPayload().getOutputStream()) {

        // Copy Input content to Output content
        byte[] b = new byte[inputstream.available()];
        int bytesRead;
        while ((bytesRead = inputstream.read(b)) >= 0) {
            outputstream.write(b, 0, bytesRead);
        }
    }
}

从Java 9开始,你可以使用 InputStream.transferTo 完全放弃字节数组。

public void transform(TransformationInput transformationInput,
                      TransformationOutput transformationOutput)
throws StreamTransformationException,
       IOException {

    try (InputStream inputstream = Base64.getDecoder().wrap(
            transformationInput.getInputPayload().getInputStream());
        OutputStream outputstream =
            transformationOutput.getOutputPayload().getOutputStream()) {

        inputstream.transferTo(outputstream);
    }
}

需要注意的是: 我不知道TransformationInput和TransformationOutput类是什么 但如果TransformationOutput代表的是一个XML文件 二进制数据将与之不兼容 因为有些字节值不允许直接出现在XML文件中。 这就是为什么XML将嵌入的二进制数据表示为十六进制或64进制的原因。

© www.soinside.com 2019 - 2024. All rights reserved.