如何将SOAP响应XML转换为Java对象?
解决方案:使用JAXB绑定SOAP响应到Java对象
既然你已经通过SOAPConnection拿到了SOAP响应,最稳妥的方式是用**JAXB(Java Architecture for XML Binding)**来将XML转换为Java对象——这也是Spring Web Services默认推荐的XML绑定方案,我帮你整理了具体的实现步骤:
1. 创建对应XML结构的Java实体类
根据你提供的SOAP响应XML,我们需要创建三个核心实体类,通过JAXB注解映射XML元素和命名空间:
1.1 响应详情类(对应<response>标签)
import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "response") @XmlAccessorType(XmlAccessType.FIELD) public class ResponseDetail { @XmlElement(name = "timestamp") private String timestamp; // 可根据实际业务改为Long类型 @XmlElement(name = "txnAmount") private String txnAmount; // 建议用BigDecimal处理金额,避免精度问题 @XmlElement(name = "userGuid") private String userGuid; @XmlElement(name = "walletSystemTxnId") private String walletSystemTxnId; // 必须添加无参构造方法(JAXB要求) public ResponseDetail() {} // 生成getter和setter方法 }
1.2 返回结果类(对应<return>标签)
import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "return") @XmlAccessorType(XmlAccessType.FIELD) public class ReturnResult { @XmlElement(name = "response") private ResponseDetail response; @XmlElement(name = "status") private String status; @XmlElement(name = "statusCode") private String statusCode; @XmlElement(name = "statusMessage") private String statusMessage; // 必须添加无参构造方法(JAXB要求) public ReturnResult() {} // 生成getter和setter方法 }
1.3 顶层响应类(对应<ns2:myResponse>标签)
注意要匹配XML里的命名空间http://impl.service.abc.com/:
import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "myResponse", namespace = "http://impl.service.abc.com/") @XmlAccessorType(XmlAccessType.FIELD) public class MyResponse { @XmlElement(name = "return") private ReturnResult returnResult; // 必须添加无参构造方法(JAXB要求) public MyResponse() {} // 生成getter和setter方法 }
2. 解析SOAP响应并转换为Java对象
修改你的代码,从SOAPMessage中提取Body内容,再用JAXB反序列化为Java对象:
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection soapConnection = soapConnectionFactory.createConnection(); // 发送请求并获取响应 SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapWithdrawAction), soapEndpointUrl); // 开始解析SOAP响应 try { // 获取SOAP Body中的目标节点 SOAPBody soapBody = soapResponse.getSOAPBody(); Node myResponseNode = soapBody.getElementsByTagNameNS("http://impl.service.abc.com/", "myResponse").item(0); // 初始化JAXB上下文 JAXBContext jaxbContext = JAXBContext.newInstance(MyResponse.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); // 将XML节点转换为Java对象 MyResponse myResponse = (MyResponse) unmarshaller.unmarshal(myResponseNode); // 现在可以直接操作对象了 System.out.println("请求状态:" + myResponse.getReturnResult().getStatusCode()); System.out.println("交易金额:" + myResponse.getReturnResult().getResponse().getTxnAmount()); } catch (JAXBException | SOAPException e) { e.printStackTrace(); } finally { soapConnection.close(); }
3. 额外优化建议
- 依赖检查:如果是Spring Boot项目,Spring Web Services已经内置JAXB依赖;普通Spring项目需手动添加
jakarta.xml.bind:jakarta.xml.bind-api和org.glassfish.jaxb:jaxb-runtime依赖。 - 类型优化:把
txnAmount改为BigDecimal、timestamp改为Long,更贴合业务数据类型。 - Spring WebServiceTemplate简化:如果用Spring的
WebServiceTemplate,可以省去手动解析SOAPMessage的步骤,直接返回Java对象:
@Autowired private WebServiceTemplate webServiceTemplate; public MyResponse callSoapService() { // 若需要发送请求对象,可传入自定义的请求实体 return (MyResponse) webServiceTemplate.marshalSendAndReceive(soapEndpointUrl); }
这样就能顺利将SOAP响应转换为Java对象了,亲测有效。
内容的提问来源于stack exchange,提问作者Geek_To_Learn
相关产品推荐
相关产品推荐

