Spring Boot SOAP服务中提取含XML的block字段字符串值问题
问题描述
我在Spring Boot中搭建了一个SOAP Web服务,请求对象里有个String类型的block字段,这个字段包含XML内容。但调用getter方法获取block字段值时,返回的是空字符串。想请教如何把它的值提取成纯字符串?
我需要将请求对象中block标签的值提取为如下格式的字符串:
"<batch> <msg_subtype>150</msg_subtype> <body>:20:O18385649 </body> <sign>MIICTgYJKoZIhvcNAQcCo</sign> </batch>"
请求的XML结构如下:
<message> <block> <batch> <msg_subtype>150</msg_subtype> <body>:20:O18385649 </body> <sign>MIICTgYJKoZIhvcNAQcCo</sign> </batch> </block> <msgCopySrvId/> <msgCopySrvInfo/> <msgDelNotifRq>N</msgDelNotifRq> <msgFinValidation/> <msgAmount>55982,55</msgAmount> </message>
我的Java代码:
public JAXBElement<SendT> createRequestXml(JAXBElement<SendT> sendT) { var message = sendT.getValue().getMessage(); if (!ObjectUtils.isEmpty(message.getBlock)) { message.setBlock(message.getBlock().replace("/", "S")); } sendT.getValue().setMessage(message); return sendT; }
XSD生成的SendT类:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "send_t", propOrder = { "message" }) public class SendT { @XmlElement(required = true) protected Params message; // getter and setter }
Params类:
public class Params { @XmlElement(required = true) protected String block; protected String msgCopySrvId; protected String msgCopySrvInfo; protected String msgDelNotifRq; protected String msgFinValidation; protected String msgAmount; //getter and setters }
解决方案
问题根源是JAXB默认会把block标签内的XML子节点当作绑定对象处理,而非纯字符串内容。以下是几种可行的解决方法:
方法1:自定义DomHandler配合@XmlAnyElement
自定义一个DomHandler实现XML内容与字符串的转换:
import javax.xml.bind.annotation.DomHandler; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.StringReader; import java.io.StringWriter; public class StringDomHandler implements DomHandler<String, StreamResult> { private StringWriter xmlWriter = new StringWriter(); @Override public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) { return new StreamResult(xmlWriter); } @Override public String getElement(StreamResult rt) { return xmlWriter.toString().trim(); } @Override public Source marshal(String n, ValidationEventHandler errorHandler) { String xml = n == null ? "" : n; return new StreamSource(new StringReader(xml)); } }
修改Params类的block字段注解:
public class Params { @XmlAnyElement(StringDomHandler.class) protected String block; // 其他字段及getter/setter保持不变 }
方法2:使用@XmlValue(适用于block无属性的场景)
如果block标签本身没有属性,仅包含内部XML内容,可直接用@XmlValue注解:
public class Params { @XmlValue protected String block; // 其他字段及getter/setter保持不变 }
注意:若block标签有自身属性,此方法会导致属性无法被解析,不适用。
方法3:修改XSD重新生成类
如果Java类是从XSD生成的,直接修改XSD中block字段的定义,指定用自定义DomHandler处理:
<xs:element name="block" type="xs:string"> <xs:annotation> <xs:appinfo> <jaxb:property> <jaxb:dom-handler handler="com.yourpackage.StringDomHandler"/> </jaxb:property> </xs:appinfo> </xs:annotation> </xs:element>
之后用XJC工具重新生成Java类,生成的Params类会自动带上正确的注解。
内容的提问来源于stack exchange,提问作者gunel
相关产品推荐
相关产品推荐

