如何使用XmlMapper序列化带命名空间的SOAP请求类?
解决方案
1. 配置命名空间与元素前缀
首先在Suchen类所在包下创建package-info.java,全局指定命名空间的前缀映射:
@XmlSchema( namespace = "http://ws1.myapi.ch/", elementFormDefault = XmlNsForm.QUALIFIED, xmlns = { @XmlNs(prefix = "ws1", namespaceURI = "http://ws1.myapi.ch/"), @XmlNs(prefix = "soapenv", namespaceURI = "http://schemas.xmlsoap.org/soap/envelope/") } ) package com.your.package; // 替换为你的实际包名 import javax.xml.bind.annotation.XmlNs; import javax.xml.bind.annotation.XmlNsForm; import javax.xml.bind.annotation.XmlSchema;
然后修改Suchen类的注解,为根元素和每个字段指定命名空间:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "benutzername", "passwort", "sprache", "datenname", "suchwerte", "einstellungen" }) @XmlRootElement(name = "Suchen", namespace = "http://ws1.myapi.ch/") public class Suchen { @XmlElement(name = "Benutzername", namespace = "http://ws1.myapi.ch/") protected String benutzername; @XmlElement(name = "Passwort", namespace = "http://ws1.myapi.ch/") protected String passwort; @XmlElement(name = "Sprache", namespace = "http://ws1.myapi.ch/") protected String sprache; @XmlElement(name = "Datenname", namespace = "http://ws1.myapi.ch/") protected String datenname; @XmlElement(name = "Suchwerte", namespace = "http://ws1.myapi.ch/") protected String suchwerte; @XmlElement(name = "Einstellungen", namespace = "http://ws1.myapi.ch/") protected String einstellungen; // 原有getter、setter、equals、hashCode方法保持不变 }
2. 构建SOAP信封结构
需要创建SOAP信封(Envelope)、头部(Header)、体部(Body)对应的POJO,才能完整生成符合要求的XML结构:
SoapEnvelope类
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "header", "body" }) @XmlRootElement(name = "Envelope", namespace = "http://schemas.xmlsoap.org/soap/envelope/") public class SoapEnvelope { @XmlElement(name = "Header", namespace = "http://schemas.xmlsoap.org/soap/envelope/") protected SoapHeader header; @XmlElement(name = "Body", namespace = "http://schemas.xmlsoap.org/soap/envelope/") protected SoapBody body; public SoapHeader getHeader() { return header; } public void setHeader(SoapHeader header) { this.header = header; } public SoapBody getBody() { return body; } public void setBody(SoapBody body) { this.body = body; } }
SoapHeader类
@XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "Header", namespace = "http://schemas.xmlsoap.org/soap/envelope/") public class SoapHeader {}
SoapBody类
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "suchen" }) @XmlRootElement(name = "Body", namespace = "http://schemas.xmlsoap.org/soap/envelope/") public class SoapBody { @XmlElement(name = "Suchen", namespace = "http://ws1.myapi.ch/") protected Suchen suchen; public Suchen getSuchen() { return suchen; } public void setSuchen(Suchen suchen) { this.suchen = suchen; } }
3. 生成完整SOAP请求XML
组装POJO并通过XmlMapper生成XML:
// 初始化业务请求对象 Suchen suchen = new Suchen(); suchen.setBenutzername("test"); suchen.setPasswort("test"); suchen.setSprache("De"); suchen.setDatenname("Arten"); suchen.setEinstellungen(""); // 组装SOAP结构 SoapBody soapBody = new SoapBody(); soapBody.setSuchen(suchen); SoapEnvelope soapEnvelope = new SoapEnvelope(); soapEnvelope.setHeader(new SoapHeader()); soapEnvelope.setBody(soapBody); // 配置XmlMapper XmlMapper xmlMapper = new XmlMapper(); xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE); xmlMapper.enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION); xmlMapper.enable(ToXmlGenerator.Feature.WRITE_XML_NAMESPACES); // 生成格式化后的XML String requestData = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(soapEnvelope);
关键说明
package-info.java用于全局绑定命名空间与前缀,确保所有关联元素自动使用指定前缀。- 所有JAXB注解必须显式指定
namespace属性,让元素与目标命名空间关联。 - 必须构建完整的SOAP信封POJO,否则只会生成
Suchen单个元素,无法满足SOAP API的请求格式要求。
内容的提问来源于stack exchange,提问作者xetra11
相关产品推荐
相关产品推荐

