Posted on 22 December 2008

Occasionally you will find that you need to create a VuGen script for a web application which changes the number of name-value pairs which are sent with a POST request. This tech tip shows you how to handle this situation by dynamically constructing a POST body.

In the example below, you can see that the web_submit_data function for the updateItemsFromSearch request (which adds items to a shopping cart) has six item IDs and six item quantities. The web_subit_data function presents the name-value pairs of the POST request in an easy to read format, but doesn't give too many clues as to how you might handle the case of submitting a varying numbers of item IDs, without writing an if statement and having separate web_submit_data functions for every possible number of items.

Fortunately, there is an easy way to do this. Read on...

 
web_submit_data("updateItemsFromSearch.do", 
	"Action=http://www.example.com.au/catalog/updateItemsFromSearch.do", 
	"Method=POST", 
	"TargetFrame=", 
	"RecContentType=text/html", 
	"Referer=http://www.example.com.au/catalog/search.do?key=0/46EF7F373045033002000000AC193D36", 
	"Snapshot=t10.inf", 
	"Mode=HTML", 
	ITEMDATA, 
	"Name=sortOption", "Value=PRICE_ASCENDING", ENDITEM, 
	"Name=pageselect", "Value=10", ENDITEM, 
	"Name=page", "Value=", ENDITEM, 
	"Name=itemPageSize", "Value=10", ENDITEM, 
	"Name=next", "Value=addToBasket", ENDITEM, 
	"Name=itemkey", "Value=46EF7F373045033002000000AC193D364785F195AFD7401600000000AC193D51", ENDITEM, 
	"Name=order", "Value=", ENDITEM, 
	"Name=itemquantity", "Value=1", ENDITEM, 
	"Name=isExtendedResult", "Value=null", ENDITEM, 
	"Name=display_scenario", "Value=products", ENDITEM, 
	"Name=contractkey", "Value=", ENDITEM, 
	"Name=contractitemkey", "Value=", ENDITEM, 
	"Name=item[0].itemID", "Value=46EF7F373045033002000000AC193D364785F195AFD7401600000000AC193D51", ENDITEM, 
	"Name=item[0].quantity", "Value=1", ENDITEM, 
	"Name=item[1].itemID", "Value=46EF7F373045033002000000AC193D3640EBE620771F00A500000000AC193D52", ENDITEM, 
	"Name=item[1].quantity", "Value=1", ENDITEM, 
	"Name=item[2].itemID", "Value=46EF7F373045033002000000AC193D363F4191CB824400F3E1000000AC193D38", ENDITEM, 
	"Name=item[2].quantity", "Value=1", ENDITEM, 
	"Name=item[3].itemID", "Value=46EF7F373045033002000000AC193D36464DB497A33B005602000000AC193D51", ENDITEM, 
	"Name=item[3].quantity", "Value=1", ENDITEM, 
	"Name=item[4].itemID", "Value=46EF7F373045033002000000AC193D36484A7C7E995A8034E1008000AC193D51", ENDITEM, 
	"Name=item[4].quantity", "Value=1", ENDITEM, 
	"Name=item[5].itemID", "Value=46EF7F373045033002000000AC193D36484E990F2564C27EE1008000AC193D35", ENDITEM, 
	"Name=item[5].quantity", "Value=1", ENDITEM, 
	LAST);

First, let's take a look at what VuGen actually sends to the web server...

 
POST /catalog/updateItemsFromSearch.do HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Cache-Control: no-cache\r\n
Referer: http://www.example.com.au/catalog/search.do?key=0/46EF7F373045033002000000AC193D36\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: en-us\r\n
Accept: */*\r\n
Connection: Keep-Alive\r\n
Host: www.example.com.au\r\n
Cookie: JSESSIONID=(J2EE5934700)ID1010337953DB11208117568232223992End; saplb_*=(J2EE5934700)5934753\r\n
Content-Length: 896\r\n
\r\n
sortOption=PRICE_ASCENDING&pageselect=10&page=&itemPageSize=10&next=addToBasket&itemkey=46
EF7F373045033002000000AC193D364785F195AFD7401600000000AC193D51&order=&itemquantity=1&isExt
endedResult=null&display_scenario=products&contractkey=&contractitemkey=&item%5B0%5D.itemI
D=46EF7F373045033002000000AC193D364785F195AFD7401600000000AC193D51&item%5B0%5D.quantity=1&
item%5B1%5D.itemID=46EF7F373045033002000000AC193D3640EBE620771F00A500000000AC193D52&item%5
B1%5D.quantity=1&item%5B2%5D.itemID=46EF7F373045033002000000AC193D363F4191CB824400F3E10000
00AC193D38&item%5B2%5D.quantity=1&item%5B3%5D.itemID=46EF7F373045033002000000AC193D36464DB
497A33B005602000000AC193D51&item%5B3%5D.quantity=1&item%5B4%5D.itemID=46EF7F37304503300200
0000AC193D36484A7C7E995A8034E1008000AC193D51&item%5B4%5D.quantity=1&item%5B5%5D.itemID=46
EF7F373045033002000000AC193D36484E990F2564C27EE1008000AC193D35&item%5B5%5D.quantity=1

As you can see, the name-value pairs that were so easy to read in the web_submit_data function are really just sent as a big blob of text, with each name-value pair separated by an ampersand (&) and some characters URL-encoded (e.g. "[" becomes "%5B").

We can make our VuGen script look more like the actual HTTP request by regenerating the script with web_custom_request selected. Select Tools > Regenerate Script, then select the recording option of URL-based script. Under URL Advanced, select Use web_custom_request only.

You script will now look something like this...

 
web_custom_request("updateItemsFromSearch.do", 
	"URL=http://www.example.com.au/catalog/updateItemsFromSearch.do", 
	"Method=POST", 
	"Resource=0", 
	"RecContentType=text/html", 
	"Referer=http://www.example.com.au/catalog/search.do?key=0/46EF7F373045033002000000AC193D36", 
	"Snapshot=t207.inf", 
	"Mode=HTTP", 
	"Body=sortOption=PRICE_ASCENDING&pageselect=10&page=&itemPageSize=10&next=addToBasket&itemkey=46EF7F373045033002000000AC193D364785F195AFD7401600000000AC193D51&order=&itemquantity=1&isExtendedResult=null&display_scenario=products&contractkey=&contractitemkey=&item%5B0%5D.itemID=46EF7F373045033002000000AC193D364785F195AFD7401600000000AC193D51&item%5B0%5D.quantity=1&item%5B1%5D.itemID=46EF7F373045033002000000AC193D3640EBE620771F00A500000000AC193D52&item%5B1%5D.quantity=1&item%5B2%5D.itemID="
	"46EF7F373045033002000000AC193D363F4191CB824400F3E1000000AC193D38&item%5B2%5D.quantity=1&item%5B3%5D.itemID=46EF7F373045033002000000AC193D36464DB497A33B005602000000AC193D51&item%5B3%5D.quantity=1&item%5B4%5D.itemID=46EF7F373045033002000000AC193D36484A7C7E995A8034E1008000AC193D51&item%5B4%5D.quantity=1&item%5B5%5D.itemID=46EF7F373045033002000000AC193D36484E990F2564C27EE1008000AC193D35&item%5B5%5D.quantity=1", 
	LAST);

The next step is to dynamically construct the string that will be sent as the body argument of the web_custom_request function. Do this by

  • Correlate your values using ORD=All (line 4) from the response to your search request (line 15).
  • Write a for loop to build a parameter containing your POST body (line 31). Save time by using lr_paramarr functions to extract the values from the parameter array you created with web_reg_save_param("Ord=All", ...).
  • Use web_custom_request to send your POST body.
 
lr_start_transaction("search for product");

// Save all item IDs returned by product search
web_reg_save_param("ItemID_array",
	"LB=Tech tips from JDS