BeanShell PostProcessor执行Java代码编译错误,无法写入CSV文件
我尝试用JMeter的BeanShell PostProcessor编写代码,将接口返回的JSON数据写入CSV文件,代码如下:
import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import com.opencsv.CSVWriter; public class CsvWrite{ public static void main(String[] args){ String response = prev.getResponseDataAsString(); JSONParser parser = new JSONParser(); File file = new File("D:\\verisk\\first_url_response.csv"); try { FileWriter fileWriter = new FileWriter(file); CSVWriter csvWriter = new CSVWriter(fileWriter); // adding header to csv String[] header = { "id", "title", "description", "price", "discountPercentage", "rating", "stock", "brand" }; csvWriter.writeNext(header); Object obj = parser.parse(response); JSONObject jsonObject = (JSONObject) obj; JSONArray productArray = (JSONArray) jsonObject.get("products"); int productArraySize = productArray.size(); for (int i = 0; i < productArraySize; i++) { JSONObject productDetailObject = (JSONObject) productArray.get(i); String id = (productDetailObject.get("id").toString()); String title = (productDetailObject.get("title").toString()); String price = (productDetailObject.get("price").toString()); String description = (productDetailObject.get("description").toString()); String discountPercentage = (productDetailObject.get("discountPercentage").toString()); String rating = (productDetailObject.get("rating").toString()); String stock = (productDetailObject.get("stock").toString()); String brand = (productDetailObject.get("brand").toString()); String[] productDetails = { id, title, description, price, discountPercentage, rating, stock, brand }; csvWriter.writeNext(productDetails) } fileWriter.close(); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行后无法写入CSV,日志报错:
2023-01-02 14:41:06,853 ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval In file: inline evaluation of: ``import java.io.File; import java.io.FileNotFoundException; import java.io.FileWr . . . '' Encountered "}" at line 44, column 25.
附带日志信息:
2023-01-02 14:41:06,853 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-1
2023-01-02 14:41:06,853 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-1
2023-01-02 14:41:06,854 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2023-01-02 14:41:06,854 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, local)
注:已将json-simple-1.1.jar和opencsv-4.1.jar放入JMeter的lib目录,代码在Eclipse中可正常运行。
问题原因与修复
语法错误:缺少分号
报错位置对应代码中csvWriter.writeNext(productDetails)一行,末尾缺少分号,BeanShell对语法要求严格,这是解析失败的直接原因。BeanShell无需类和main方法
BeanShell PostProcessor直接执行脚本代码,不需要像Java类那样定义CsvWrite类和main方法,多余的类结构会导致执行异常。
修正后的代码
import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import com.opencsv.CSVWriter; // 获取接口响应数据 String response = prev.getResponseDataAsString(); JSONParser parser = new JSONParser(); File file = new File("D:\\verisk\\first_url_response.csv"); try { FileWriter fileWriter = new FileWriter(file); CSVWriter csvWriter = new CSVWriter(fileWriter); // 写入CSV表头 String[] header = { "id", "title", "description", "price", "discountPercentage", "rating", "stock", "brand" }; csvWriter.writeNext(header); Object obj = parser.parse(response); JSONObject jsonObject = (JSONObject) obj; JSONArray productArray = (JSONArray) jsonObject.get("products"); int productArraySize = productArray.size(); for (int i = 0; i < productArraySize; i++) { JSONObject productDetailObject = (JSONObject) productArray.get(i); String id = productDetailObject.get("id").toString(); String title = productDetailObject.get("title").toString(); String price = productDetailObject.get("price").toString(); String description = productDetailObject.get("description").toString(); String discountPercentage = productDetailObject.get("discountPercentage").toString(); String rating = productDetailObject.get("rating").toString(); String stock = productDetailObject.get("stock").toString(); String brand = productDetailObject.get("brand").toString(); String[] productDetails = { id, title, description, price, discountPercentage, rating, stock, brand }; csvWriter.writeNext(productDetails); // 补充分号 } // 正确关闭资源 csvWriter.close(); fileWriter.close(); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
额外优化建议
- 优先使用JSR223 PostProcessor + Groovy替代BeanShell,Groovy性能更优,语法兼容性更强。
- 若需要保留历史数据,可将
FileWriter(file)改为FileWriter(file, true)启用追加模式。
内容的提问来源于stack exchange,提问作者Sandesh

