java - 使用 Base64 编码字符串的 XML 到 PDF

标签 java xml java-8 base64 decode

我有一个 XML,其中我获取了一个 Base64 编码字符串形式的 PDF 文档。

<?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 内容作为输入并执行 Base 64 转换。

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 。任何帮助将不胜感激。

最佳答案

来自the documentation of InputStream.available() :

It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.

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

您还需要记住关闭您的信息流。如果不这样做,就会造成内存泄漏,并且某些数据可能无法写入 OutputStream。

Base64.Decoder有一个有用的方法,wrap(InputStream) ,它允许您将解码视为普通的输入流。

最后:永远不要编写空的 catch block 。如果您不确定如何处理异常,那么不要删除 try/catch,将 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 的原因。

关于java - 使用 Base64 编码字符串的 XML 到 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62281272/

相关文章:

xml - 如何使用 VBScript 和 XPATH 查找 XML 中元素的序号位置

java - GWT 类成员命名

java - 在我的 android 编程代码 java.lang 中出现错误

xml - 如何将 Perl 的 XML::XPath 与非英文元素名称一起使用?

c# - 在 C# 的 excel 文档中执行查找和替换

Java lambda 表达式 : Combinator-Pattern Improvement

java - 在编码之前动态隐藏一些字段(java 到 json)

java - 在 Java 8 中使用Optional.empty 默认可选 orElse

java - 整型和浮点型字面量指向和使用?

java - volatile关键字没有用 当使用synchronized时?