【问题标题】:Decode base64 PDF and write to file in JMeter解码base64 PDF并在JMeter中写入文件
【发布时间】:2017-03-28 20:34:28
【问题描述】:

我正在尝试从响应中解码 pdf 并将其写入文件。

文件已创建并且文件大小似乎正确,但是当我打开它时,我收到一条错误消息:“打开此文档时出错。文件已损坏,无法打开修复。

我正在使用来自this post 的代码来解码和创建文件。

我将API返回的base64编码文件设置为变量vars.get("documentText")

这是我的 BeanShell PostProcessor 代码的外观:

import org.apache.commons.io.FileUtils;
import org.apache.commons.codec.binary.Base64;

String Createresponse= vars.get("documentText");
vars.put("response",new String(Base64.decodeBase64(Createresponse.getBytes("UTF-8"))));

Output = vars.get("response");

f = new FileOutputStream("C:\\Users\\user\\Desktop\\Test.pdf");
p = new PrintStream(f); 
this.interpreter.setOut(p); 
print(Output);
f.close();

我是不是做错了什么?

我也做了以下,但得到了相同的结果:

byte[] data = Base64.decodeBase64(vars.get("documentText"));
FileOutputStream out = new FileOutputStream("C:\\Users\\user\\Desktop\\Test.pdf");
out.write(data);
out.close();

编辑:

Response 中的整个 PDF 如下所示:(这些只是前 5 行(大约 7,548 行),但它们都相似):

JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP7/KQovQ3JlYXRvciAo/v8pCi9Qcm9kdWNlciAo
/v8AUQB0ACAANQAuADUALgAxKQovQ3JlYXRpb25EYXRlIChEOjIwMTcwMzI3MTgwNTEzKQo+Pgpl
bmRvYmoKMiAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMyAwIFIKPj4KZW5kb2JqCjQg
MCBvYmoKPDwKL1R5cGUgL0V4dEdTdGF0ZQovU0EgdHJ1ZQovU00gMC4wMgovY2EgMS4wCi9DQSAx
LjAKL0FJUyBmYWxzZQovU01hc2sgL05vbmU+PgplbmRvYmoKNSAwIG9iagpbL1BhdHRlcm4gL0Rl

我假设这是导致问题的原因?有没有办法将响应转换为可以解码的单个字符串?

编辑 2:

所以回复中的
 绝对是我的问题。我查找了hex code character,它转换为回车。如果我从 JMeter 中手动复制 Response,将其粘贴到 Notepad++ 中,删除 
,然后手动解码,PDF 会正常打开。

我尝试修改我的 BeanShell 脚本以删除回车然后对其进行解码,但它仍然不能完全正常工作。 PDF 现在打开,但是,它只是空白的白页。这是我更新的代码:

String Createresponse= vars.get("documentText");
String b64 = Createresponse.replace("
","");
vars.put("response",new String(Base64.decodeBase64(b64)));

Output = vars.get("response");

f = new FileOutputStream("C:\\Users\\user\\Desktop\\Test.pdf");
p = new PrintStream(f); 
this.interpreter.setOut(p); 
print(Output);
f.close();

【问题讨论】:

  • 你能检查一下查看结果树中的 pdf 响应是什么吗?你可以参考这篇文章来了解如何阅读。 dzone.com/articles/how-to-read-a-pdf-file-in-apache-jmeter
  • 解码应该使用字符串。 getBytes("UTF-8") 可能返回错误。
  • 我已经更新了问题,并举例说明了 PDF 响应的前几行是什么样的

标签: java jmeter beanshell


【解决方案1】:

这对我有用。你输入的数据有误。

package com.test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;

import org.junit.Test;

public class TestBase64 {

    String data = 
"JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP7/KQovQ3JlYXRvciAo/v8pCi9Qcm9kdWNlciAo/v8AUQB0ACAANQAuADUALgAxKQovQ3JlYXRpb25EYXRlIChEOjIwMTcwMzI3MTgwNTEzKQo+Pgpl";
@Test
    public void decodeBase64()
    {
        byte[] localData = Base64.getDecoder().decode(data);

        try (FileOutputStream out = new FileOutputStream("/testout64.dat"))
        {
            out.write(localData);

            out.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

这会导致

%PDF-1.4
1 0 obj
<<
/Title (þÿ)
/Creator (þÿ)
/Producer (þÿ Q t   5 . 5 . 1)
/CreationDate (D:20170327180513)
>>
e

并且似乎是有效的 PDF。 &_#_x_d_;_ 部分是什么?好像是一些自定义格式的字符。

【讨论】:

  • 此代码在 JMeter 中不适用于我。我试图操纵它,但到目前为止还没有运气。我的原始代码似乎工作正常,问题在于 API 响应中 PDF 的格式设置方式
  • 我没有设置 JMeter。尝试在关闭“f”之前刷新“p”。您可以在发送来自打印流的所有数据之前关闭文件输出流。顺便说一句:您的变量命名与任何 java 样式指南都不匹配。
  • 这不是我的原始代码。我只是想让它工作,然后我肯定会回去重构它。顺便说一句,在关闭 f 之前冲洗 p 对我的结果没有影响。 (还是)感谢你的建议。我可能仍会将其保留在最终版本中
【解决方案2】:

我基本上已经回答了我的问题,问题在于我尝试解码的 base64 编码响应是多行的,并且包含回车十六进制代码。

我对此的解决方案是从响应中删除回车十六进制代码并将其压缩为单个 base64 编码文本字符串,然后将文件写出。

import org.apache.commons.io.FileUtils;
import org.apache.commons.codec.binary.Base64;

String response = vars.get("documentText");
String encodedFile = response.replace("&#xd;","").replaceAll("[\n]+","");

// Decode the response
vars.put("decodedFile",new String(Base64.decodeBase64(encodedFile)));

// Write out the decoded file
Output = vars.get("decodedFile");
file = new FileOutputStream("C:\\Users\\user\\Desktop\\decodedFile.pdf");
p = new PrintStream(file); 
this.interpreter.setOut(p); 
print(Output);
p.flush();
file.close();

【讨论】:

    猜你喜欢
    • 2014-06-22
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 2019-10-22
    • 2021-02-22
    • 2016-01-13
    相关资源
    最近更新 更多