Prasad
Prasad

Reputation: 686

Issue while sending a JSON object with BeanShell PreProcessor

I want to send one JSON Object to the HTTP Request body in JMeter using the BeanShell PreProcessor. To model the JSON object I am using java code (with some business logic). Hence I created one BeanShell PreProcessor and wrote the java code as follows,

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

    String key="testKey";
    int lastID=5548;
    int totalCount=198;
    JSONObject obj1 = new JSONObject();
    JSONArray obj2 = new JSONArray();
    for (int i=1;i<=totalCount;i++)
    {
        JSONObject item = new JSONObject();
        item.put("taskId", Integer.toString(lastID+i));
        item.put("taskOrder",1);
        item.put("snapshotTemplateKey",key);
        obj2.put(item);
        obj1.put("changeControlTasks", obj2);
        obj1.put("ccName","Eleven" );
        obj1.put("snapshotTemplateKey",key);
    }
    log.info(obj1);
    vars.putObject("jsonData",obj1);

And in the HTTP request body, I am trying to fetch the data as follows,

${jsonData}

With the above code, It is throwing the below shared error

Request :

POST data:
${jsonData}

Error in the logs:

2017/08/06 07:27:10 ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval
Sourced file: inline evaluation of: ``import org.json.JSONArray; import org.json.JSONException; 
import org.json.JSONOb . . . '' : Error in method invocation: Method info(  ) not found in class'org.apache.log.Logger'

Can any one suggest what is issue with above code and how to resolve the same.

any suggestions or solutions will also be appreciated.

Upvotes: 3

Views: 3211

Answers (2)

Dmitri T
Dmitri T

Reputation: 168122

  1. Your Beanshell won't work as it will fail at this line:

    log.info(obj1); 
    

    as you won't be able to print a JSON Object into the log

  2. Even if you work it around your HTTP Request sampler won't work for the same reason: you cannot put a JSON Object as a body data as JMeter expects a String there
  3. Beanshell is not the best scripting option, when you run your test with high number of threads this function will become the bottleneck, you should consider switching to JSR223 PreProcessor and Groovy language instead. Groovy has built-in JSON support and its performance is much better as well-behaved Groovy scripts can be compiled and cached. The substitution Groovy code would be something like:

    import groovy.json.JsonBuilder
    
    def key = 'testKey'
    def lastID = 5548
    def totalCount = 198
    
    JsonBuilder builder = new JsonBuilder()
    
    def array = []
    1.upto(totalCount, {
        def taskId = (lastID + "${it}".toInteger())
        array << [getKey: { key }, getTaskId: { taskId }, getTaskOrder: { 1 }]
    
    })
    
    builder(
            {
                changeControlTasks array.collect() {
                    [
                            "snapshotTemplateKey": it.getKey(),
                            "taskId"             : it.getTaskId(),
                            "taskOrder"          : it.getTaskOrder()
                    ]
                }
                snapshotTemplateKey "testKey"
                ccName "Eleven"
            }
    )
    
    vars.put('jsonData', builder.toPrettyString())
    

Upvotes: 0

Ori Marko
Ori Marko

Reputation: 58812

obj2 hold the data. Use obj2 instead of obj1:

 vars.putObject("jsonData",obj2);

For log convert toSring

 log.info(obj1.toString());

Upvotes: 1

Related Questions