如何在SOAP UI中捕获请求的接收时间?
Hey there! Let's figure out how to tackle your SoapUI problem—you need to capture the exact time a request is received, then return the response with the largest timestamp that's still smaller than that receive time. This is totally doable with Groovy scripting (which SoapUI supports natively), so let's break it down:
1. Capture the Request Receive Time in Your Mock Service
Since you're setting up a response based on incoming requests, you'll want to use the On Request Script of your SoapUI Mock Service. This script runs the moment SoapUI receives a request, so grabbing the time here gives you the most accurate "receive time" stamp:
// Grab the exact timestamp (in milliseconds) when the request is received def requestReceivedTime = System.currentTimeMillis() // Store it in the context so we can use it later in the script context.requestReceivedTime = requestReceivedTime log.info("Request received at timestamp: ${requestReceivedTime}")
2. Prepare Your Predefined Responses
Next, you'll need to organize your responses along with their timestamp values. You can either define them directly in the script, or pull them from existing Mock Responses you've already created.
Option A: Define Responses in the Script
If you want to hardcode your responses (great for testing), structure them as a list of maps with timestamps and response content:
// Example list of predefined responses with their timestamps def predefinedResponses = [ [timestamp: 1689999000000, response: '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><!-- Your response content here --></soapenv:Body></soapenv:Envelope>'], [timestamp: 1689999500000, response: '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><!-- Another response content here --></soapenv:Body></soapenv:Envelope>'], [timestamp: 1690000000000, response: '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><!-- Latest valid response content here --></soapenv:Body></soapenv:Envelope>'] ]
Option B: Pull Responses from Existing Mock Responses
If you already have Mock Responses set up in SoapUI, you can parse their timestamp tags directly:
// Get all existing Mock Responses in your Mock Service def allMockResponses = mockService.getMockResponses() def validMockResponses = [] // Loop through each response to extract its timestamp allMockResponses.each { mockResp -> def responseContent = mockResp.getContent() // Use regex to pull the timestamp value from your <timestamp> tag def timestampMatch = (responseContent =~ /<timestamp>(\d+)<\/timestamp>/) if (timestampMatch.find()) { def respTimestamp = timestampMatch.group(1).toLong() // Only keep responses where timestamp is less than request receive time if (respTimestamp < context.requestReceivedTime) { validMockResponses.add([timestamp: respTimestamp, mockResponse: mockResp]) } } }
3. Select the Correct Response
Now filter and pick the response with the largest valid timestamp:
For Predefined Script Responses
// Filter responses to only those with timestamps < request receive time def validResponses = predefinedResponses.findAll { it.timestamp < context.requestReceivedTime } // Pick the response with the biggest timestamp (or use a default if none exist) def selectedResponse = validResponses ? validResponses.max { it.timestamp } : null // Set the Mock Service to return this response if (selectedResponse) { mockResponse.setContent(selectedResponse.response) log.info("Returning response with timestamp: ${selectedResponse.timestamp}") } else { // Fallback to a default response if no valid options exist mockResponse.setContent('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body>No matching response found</soapenv:Body></soapenv:Envelope>') log.warn("No valid responses available for request received at ${context.requestReceivedTime}") }
For Existing Mock Responses
if (!validMockResponses.isEmpty()) { // Grab the response with the largest valid timestamp def selectedMockResp = validMockResponses.max { it.timestamp }.mockResponse // Tell the Mock Service to return this response context.mockResponse = selectedMockResp log.info("Returning existing Mock Response with timestamp: ${validMockResponses.max { it.timestamp }.timestamp}") } else { // Fallback to default content if no valid responses exist mockResponse.setContent('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body>No valid response available</soapenv:Body></soapenv:Envelope>') }
Quick Notes
- Timestamp Format: Make sure your response timestamps are consistent! If you're using human-readable dates (like
yyyy-MM-dd HH:mm:ss) instead of millisecond timestamps, convert them to timestamps first with this snippet:def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss") def respDate = dateFormatter.parse("2023-07-30 10:00:00") def respTimestamp = respDate.getTime() - Testing: Use the SoapUI log panel to verify the request receive time and selected response timestamp—this helps debug if things aren't working as expected.
内容的提问来源于stack exchange,提问作者Adam Leppek

