JSON转XML转换报错:无法从START_ARRAY反序列化HashMap(Groovy求助)
Hey there! Let's break down why you're hitting this error and get your JSON-to-XML script working smoothly.
What's Causing the Error?
That error message is telling you exactly the issue: your payload is a JSON array (wrapped in []) instead of a single JSON object (wrapped in {}). Groovy tries to deserialize single JSON objects as HashMaps, but arrays get turned into Lists—so when your code treats it like a single object, it throws a fit.
For example, your input might look like this (array):
[{"AdditionalInfo": {"ClientEmail": "test@example.com"}, "Amount": 100, "WithdrawalId": "123"}]
Instead of this (single object):
{"AdditionalInfo": {"ClientEmail": "test@example.com"}, "Amount": 100, "WithdrawalId": "123"}
How to Fix It
We’ll adjust the code to handle both scenarios—either processing multiple items from an array, or grabbing the first item if the payload was accidentally wrapped in brackets.
Option 1: Process a JSON Array (Multiple Items)
If your payload is supposed to be an array, modify the script to loop through each entry and generate corresponding XML nodes:
import groovy.xml.StreamingMarkupBuilder import groovy.xml.XmlUtil def xmlBuilder = new StreamingMarkupBuilder() def payloadItems = payload // payload is a List here writer = xmlBuilder.bind { mkp.declareNamespace( ns1: "TV") 'ns1:transfers' { // Plural root node to wrap multiple transfer entries payloadItems.each { item -> 'ns1:transfer' { // Fixed typo: "tranfer" → "transfer" 'merchant_id'() 'surveyYear'() 'merchant_password' () 'email'(item.AdditionalInfo?.ClientEmail) // Use ?. to avoid null pointers if AdditionalInfo is missing 'amount'(item.Amount) 'reference_code'(item.WithdrawalId) } } } } return XmlUtil.serialize(writer)
Option 2: Handle a Single Object (Accidental Array)
If your payload should be a single object but is wrapped in an array, adjust the code to extract the first element:
import groovy.xml.StreamingMarkupBuilder import groovy.xml.XmlUtil def xmlBuilder = new StreamingMarkupBuilder() // Check if payload is a list—if so, take the first item; else use it directly def item = payload instanceof List ? payload[0] : payload writer = xmlBuilder.bind { mkp.declareNamespace( ns1: "TV") 'ns1:transfer' { // Fixed typo: "tranfer" → "transfer" 'merchant_id'() 'surveyYear'() 'merchant_password' () 'email'(item.AdditionalInfo?.ClientEmail) 'amount'(item.Amount) 'reference_code'(item.WithdrawalId) } } return XmlUtil.serialize(writer)
Quick Debug Tips
- Add a line to confirm your payload type:
If it printsprintln "Payload type: ${payload.getClass().name}"java.util.ArrayList, you’re dealing with an array. If it’sjava.util.LinkedHashMap, it’s a single object. - The safe navigation operator
?.prevents null pointer exceptions ifAdditionalInfois missing from any item. - Fixed the typo in
ns1:tranfertons1:transfer(assuming that was a small mistake in your original code).
内容的提问来源于stack exchange,提问作者xkvt

