Java - 从 URL 获取 PDF 并返回 BASE64 字符串

问题描述

我有以下任务从 URL 获取 PDF 并返回 BASE64 字符串。

我目前拥有的(抱歉我不是 Java 专家):

public String readPDFSOAP(String var,Container container) throws StreamTransformationException{
try {
        //get the url page from the arguments array
        URL url = new URL("URLPDF");
        try {
            //get input Stream from URL
                            InputStream in = new BufferedInputStream(url.openStream());
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buf = new byte[131072];
            int n = 0;
            while (-1 != (n = in.read(buf))) {
                out.write(buf,n);
            }
            out.close();
            in.close();
            byte[] response = out.toByteArray();
                            String string = new String(response);
            
        } catch (Exception e) {
            e.printstacktrace();
        }
    } catch (Exception e) {
        e.printstacktrace();
    }return String;}

但是字符串无法返回。 任何帮助表示赞赏。

谢谢, 朱利安

解决方法

你的代码是各种各样的错误。首先,使用 Base64 类来处理字节数组的编码。并且无需将其分配给变量,只需返回即可。

return Base64.getEncoder().encodeToString(response)

在你的最后一行,在你的 try/catch 块之外,抛出一个异常。如果您到达那里,那么您将无法正确检索和编码响应,因此无需返回值。您处于错误状态。

,

使用java.util.Base64

PDF 文件可能很大。直接对 InputStream 进行编码,而不是将其读入内存:

ByteArrayOutputStream out = new ByteArrayOutputStream();

try (InputStream in = new BufferedInputStream(url.openStream())) {
    in.transferTo(Base64.getEncoder().wrap(out));
}

String base64 = out.toString(StandardCharsets.US_ASCII);

Base64 编码的版本甚至比原始文件还要大。我不知道你打算用编码版本做什么,但如果你打算把它写在某个地方,你想避免将文件的任何版本——原始的或编码的——保存在内存中。你可以通过让你的方法接受一个 OutputStream 作为参数来做到这一点:

public void readPDFSOAP(OutputStream destination,String var,Container container)
throws StreamTransformationException,IOException {

    URL url = new URL("https://example.com/doc.pdf");
    try (InputStream in = new BufferedInputStream(url.openStream())) {
        in.transferTo(Base64.getEncoder().wrap(destination));
    }
}

更新:

既然你说过不能使用 try-with-resources 语句:

try-with-resources statement 只是一种保证 InputStream(或其他可关闭资源)关闭的便捷方式。这:

try (InputStream in = new BufferedInputStream(url.openStream())) {
    // code that uses 'in'
}

(几乎)等同于:

InputStream in = null;

try {
    in = new BufferedInputStream(url.openStream());
    // code that uses 'in'
} finally {
    if (in != null) {
        try {
            in.close();
        } catch (IOException e) {
            // Suppress
        }
    }
}