LoadRunner中拦截SOAP响应并解析EXI编码XML的方案求助
Got it, let's work through how to adapt your existing LoadRunner XML-based scripts to handle this SOAP response with Base64-encoded EXI XML. The core idea is to intercept the SOAP response, use your MyEXIEncoder class to decode and convert the content into plain XML, then replace the original response so your existing correlation rules work as-is.
Core Approach
LoadRunner lets you hook into response processing either via custom C functions (for C-based scripts) or directly via Java code (for Java Vusers). We'll cover both scenarios since you might have either script type:
- Extract the Base64 string from the
<RootElement>CDATA section - Call your
MyEXIEncoderto handle Base64 decoding + EXI-to-XML conversion - Replace the encoded content in the original SOAP response with the plain XML, so your existing correlation logic can pick up values normally
Step-by-Step Implementation
1. Prepare Your Java Class for LoadRunner
First, package your MyEXIEncoder.class into a JAR file (e.g., MyEXIEncoder.jar). Then add this JAR to LoadRunner's classpath:
- Open your script in VuGen → Go to Runtime Settings → Java → Classpath → Click "Add" and select your JAR file.
2. C-Based LoadRunner Scripts (Most Common)
Use LoadRunner's web_reg_response_filter to attach a custom handler that modifies the response before your correlation logic runs. Here's a working example:
// Custom response handler to parse EXI content int processEXIResponse(char *originalResponse, char **modifiedResponse, void *userData) { char base64Content[10240] = {0}; // Extract the Base64 string from the SOAP response's RootElement lr_xml_get_values("XML={originalResponse}", "Query=/SOAP:Envelope/SOAP:Body/RootElement/text()", "ValueParam=BASE64_DATA", "IgnoreNamespaces=Yes", // Skip namespace headaches if needed LAST); strcpy(base64Content, lr_eval_string("{BASE64_DATA}")); // Call your MyEXIEncoder Java class to decode and convert jclass encoderClass = lr_java_class_find("MyEXIEncoder"); jobject encoderInstance = lr_java_instance_create(encoderClass, "()V", NULL); // Assume your class has a method: public String decodeAndConvert(String base64Input) jstring base64Input = lr_java_string_create(base64Content); jstring parsedXml = (jstring)lr_java_method_invoke(encoderInstance, "decodeAndConvert", "(Ljava/lang/String;)Ljava/lang/String;", base64Input); char *plainXml = lr_java_string_get(parsedXml); // Build the modified SOAP response with plain XML char newResponse[102400] = {0}; // Grab everything before <RootElement> strncpy(newResponse, originalResponse, strstr(originalResponse, "<RootElement>") - originalResponse); strcat(newResponse, "<RootElement>"); strcat(newResponse, plainXml); strcat(newResponse, "</RootElement>"); // Append the rest of the original response after </RootElement> strcat(newResponse, strstr(originalResponse, "</RootElement>") + strlen("</RootElement>")); // Pass the modified response back to LoadRunner *modifiedResponse = (char *)malloc(strlen(newResponse) + 1); strcpy(*modifiedResponse, newResponse); // Clean up Java resources to avoid leaks lr_java_string_free(base64Input); lr_java_string_free(parsedXml); lr_java_instance_destroy(encoderInstance); lr_java_class_release(encoderClass); return 0; } Action() { // Register the response filter BEFORE making the SOAP call web_reg_response_filter("FilterFunc=processEXIResponse", LAST); // Your existing SOAP request (unchanged) web_service_call("StepName=FetchData", "SOAPMethod=YourNamespace|YourPort|YourOperation", "URL=http://your-webservice-endpoint.com", "SOAPEnvelope=<?xml version=\"1.0\" encoding=\"utf-8\"?>" "<SOAP:Envelope xmlns:SOAP=\"http://schemas.xmlsoap.org/soap/envelope/\">" "<SOAP:Body>" "<YourRequestPayload>...</YourRequestPayload>" "</SOAP:Body>" "</SOAP:Envelope>", LAST); // Your existing correlation logic (works with the modified plain XML response) web_reg_save_param_ex("ParamName=TargetValue", "XML={response}", "Query=/RootElement/YourTargetNode/text()", LAST); return 0; }
3. Java Vuser Scripts (Simpler for Java-Based Workflows)
If you're using Java Vusers, you can directly manipulate the response in code without C interop:
import com.yourpackage.MyEXIEncoder; import lr.*; public class Actions { public int init() throws Throwable { return 0; } public int action() throws Throwable { // Send your existing SOAP request and capture the response WebServiceCaller.call("StepName=FetchData", "SOAPMethod=YourNamespace|YourPort|YourOperation", "URL=http://your-webservice-endpoint.com", "SOAPEnvelope=<?xml version=\"1.0\" encoding=\"utf-8\"?>" "<SOAP:Envelope xmlns:SOAP=\"http://schemas.xmlsoap.org/soap/envelope/\">" "<SOAP:Body>" "<YourRequestPayload>...</YourRequestPayload>" "</SOAP:Body>" "</SOAP:Envelope>", "ResponseParam=ORIGINAL_RESPONSE"); // Extract the Base64 string from the response String originalResp = lr.evalString("{ORIGINAL_RESPONSE}"); int startIdx = originalResp.indexOf("<RootElement><![CDATA[") + "<RootElement><![CDATA[".length(); int endIdx = originalResp.indexOf("]]></RootElement>"); String base64Str = originalResp.substring(startIdx, endIdx); // Use your custom class to parse to plain XML MyEXIEncoder encoder = new MyEXIEncoder(); String plainXml = encoder.decodeAndConvert(base64Str); // Build the modified response and store it in a parameter String modifiedResp = originalResp.substring(0, startIdx) + plainXml + originalResp.substring(endIdx); lr.setParam("MODIFIED_RESPONSE", modifiedResp); // Your existing correlation logic (uses the modified response parameter) lr.saveParamXml("TargetValue", "XML={MODIFIED_RESPONSE}", "Query=/RootElement/YourTargetNode/text()"); return 0; } public int end() throws Throwable { return 0; } }
Key Notes
- Double-check that your
MyEXIEncodermethod signature matches what LoadRunner is calling (e.g., if your method handles large payloads, adjust buffer sizes in the C script). - Test the
MyEXIEncoderclass standalone first to confirm it correctly decodes Base64 and converts EXI to XML—this avoids debugging integration issues later. - For C scripts, be mindful of memory management (free any
malloc'd memory to prevent leaks). - If your SOAP response uses complex namespaces, add
IgnoreNamespaces=Yestolr_xml_get_valuesor specify the namespace in your XPath query.
内容的提问来源于stack exchange,提问作者The g

