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

Spring Boot中Java对象转XML并生成标准SOAP信封的问题

Spring Boot生成标准SOAP信封及调整XML输出方案

1. 移除XML声明

在JAXB的Marshaller中设置jaxb.fragment属性为true,即可自动移除XML声明(<?xml version="1.0" encoding="UTF-8"?>)。

2. 定义标准SOAP信封结构

创建对应SOAP规范的JAXB实体类,用来封装业务对象:

SoapEnvelope类

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Envelope", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapEnvelope {
    @XmlElement(name = "Header", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapHeader header;

    @XmlElement(name = "Body", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapBody body;

    // 生成getter、setter方法
}

SoapHeader类

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;

@XmlAccessorType(XmlAccessType.FIELD)
public class SoapHeader {
    // 如需自定义Header内容,添加对应字段;无需则留空即可
}

SoapBody类

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class SoapBody {
    @XmlElement(name = "Bookstore", namespace = "http://your-web-namespace")
    private Bookstore bookstore;

    // 生成getter、setter方法
}

3. 修正命名空间前缀(替换ns2为web)

在Bookstore实体类所在的包下创建package-info.java,指定业务命名空间及对应前缀:

@XmlSchema(
    namespace = "http://your-web-namespace",
    elementFormDefault = XmlNsForm.QUALIFIED,
    xmlns = {
        @XmlNs(prefix = "web", namespaceURI = "http://your-web-namespace")
    }
)
package com.your.package.model; // 替换为Bookstore所在的实际包路径

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

同时,确保Bookstore类的@XmlRootElement或@XmlType指定的命名空间与上述一致:

@XmlRootElement(name = "Bookstore", namespace = "http://your-web-namespace")
public class Bookstore {
    // 原有字段及JAXB注解
}

4. Controller中整合转换逻辑

修改Controller代码,将业务对象包装到SOAP信封,并配置Marshaller:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import com.sun.xml.bind.namespacePrefixMapper;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.StringWriter;

@RestController
public class SoapController {

    private final JAXBContext jaxbContext;

    // 构造注入JAXBContext,包含SoapEnvelope、Bookstore等类
    public SoapController() throws JAXBException {
        this.jaxbContext = JAXBContext.newInstance(SoapEnvelope.class, Bookstore.class);
    }

    @GetMapping("/soap/bookstore")
    public ResponseEntity<String> generateSoapResponse() throws JAXBException {
        // 1. 初始化业务对象
        Bookstore bookstore = new Bookstore();
        // 填充bookstore数据...

        // 2. 包装到SOAP信封
        SoapEnvelope soapEnvelope = new SoapEnvelope();
        SoapBody soapBody = new SoapBody();
        soapBody.setBookstore(bookstore);
        soapEnvelope.setBody(soapBody);
        soapEnvelope.setHeader(new SoapHeader()); // 无需Header可设为null

        // 3. 配置Marshaller
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); // 移除XML声明
        // 指定命名空间前缀映射
        marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
            @Override
            public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
                if ("http://schemas.xmlsoap.org/soap/envelope/".equals(namespaceUri)) {
                    return "soap";
                } else if ("http://your-web-namespace".equals(namespaceUri)) {
                    return "web";
                }
                return suggestion;
            }
        });

        // 4. 转换为XML字符串
        StringWriter writer = new StringWriter();
        marshaller.marshal(soapEnvelope, writer);
        String soapXml = writer.toString();

        // 5. 返回SOAP响应
        return ResponseEntity.ok()
                .contentType(MediaType.TEXT_XML)
                .body(soapXml);
    }
}

注意事项

  • 若使用Spring Boot 3+,需替换javax.xml.bind相关包为jakarta.xml.bind,并确保引入Jakarta XML Binding依赖。
  • NamespacePrefixMapper属于JAXB实现类,需确保项目中包含jaxb-impl依赖(Maven可直接引入)。

内容的提问来源于stack exchange,提问作者The Rock

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:57:50