You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:40:15