使用Savon调用SOAP服务遇请求无效,寻求专业排查支持
getProductSellable SOAP Operation I feel your pain—working with SOAP and Savon can be such a slog, especially when you know your XML works in the provider's validator but can't get it to play nice with the gem. Let's walk through the most likely fixes based on the details you shared:
First, Let's Recap Your Setup
- Web Service: ProductData (v1.0.0)
- Operation:
getProductSellable - Endpoint:
https://psproductdata100-stg.pcna.online - Valid XML request (partial):
<GetProductSellableRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ww...
1. Fix Your Savon Client Initialization
The biggest culprit with Savon issues is almost always namespaces. Your valid XML uses a specific xmlns value (even though it's cut off), so you need to make sure your client is configured to use that exact namespace. Here's a sample setup:
client = Savon.client( endpoint: "https://psproductdata100-stg.pcna.online", namespace: "http://your-full-namespace-here", # Replace with the full xmlns from your valid XML namespaces: { "xsi" => "http://www.w3.org/2001/XMLSchema-instance" # Match the xsi namespace from your XML }, log: true, # Enable logging to debug the request/response logger: Logger.new(STDOUT) # Print logs to console )
Pro tip: If the provider offers a WSDL (try appending ?wsdl to the endpoint URL), use wsdl: "https://psproductdata100-stg.pcna.online?wsdl" instead of manually setting namespaces—Savon will auto-populate them for you, which avoids typos.
2. Mirror Your Valid XML Exactly in the Savon Call
Since your XML works in the validator, the easiest test is to pass that raw XML directly to Savon to rule out any generation issues. Here's how:
valid_xml = "<GetProductSellableRequest xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://your-full-namespace'>...</GetProductSellableRequest>" response = client.call(:get_product_sellable, raw: true, message: valid_xml)
If this works, the problem was with how Savon was generating the XML. If not, check for authentication requirements or endpoint mismatches.
If you prefer using Savon's message hash syntax, make sure your structure matches the valid XML exactly. For example:
response = client.call(:get_product_sellable, message: { # Add all elements from your valid XML here—case and nesting matter! "ProductId" => "12345", "Region" => "US" } )
3. Check for Common Gotchas
- Case Sensitivity: SOAP operations and element names are often case-sensitive. Double-check if the operation is
getProductSellable(camelCase) orGetProductSellable(PascalCase) in the provider's docs/WSDL. - SOAP Version: Some services require SOAP 1.2 instead of the default 1.1. Add
soap_version: 1.2to your client setup if needed. - Authentication: Don't forget to add any required auth (basic auth, API keys in headers). For example:
client = Savon.client( # ... other options basic_auth: ["your-username", "your-password"], headers: { "X-API-Key" => "your-api-key" } ) - Logging: Use the
log: trueoption I mentioned earlier to compare the XML Savon sends with your valid XML. Look for missing namespaces, incorrect element casing, or extra attributes that might be breaking the request.
4. Verify the Operation Name
Sometimes the WSDL defines the operation name differently than the request element name. For example, the operation might be getProductSellable but the request element is GetProductSellableRequest. Use client.operations to list all available operations from the WSDL (if you're using it) to confirm:
puts client.operations # Prints all valid operation names
If none of these steps fix the issue, share the error message you're getting (SOAP fault, HTTP status code, etc.) and the full valid XML, and we can troubleshoot further.
内容的提问来源于stack exchange,提问作者timsabat

