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

如何通过REST接收SOAP信封?基于JAX-RS接口的客户端实现咨询

实现Jersey客户端调用返回SOAP信封的JAX-RS服务

咱们先理清核心背景:你的服务返回SOAP格式的XML信封,同时你已经有从WADL/XSD生成的MyResponse类(对应ns2:myResponse节点),还有基于JAX-RS定义的接口。下面提供两种实用的客户端实现方式:


方式一:手动解析SOAP信封,提取目标响应对象

这种方式不需要额外生成SOAP信封的JAXB类,直接通过DOM定位到目标节点后解析,适合快速实现。

1. 准备依赖

确保项目引入Jersey核心客户端、JAXB支持模块:

<!-- Jersey 1.x 客户端核心 -->
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.19.4</version>
</dependency>
<!-- Jersey JAXB 解析支持 -->
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-jaxb</artifactId>
    <version>1.19.4</version>
</dependency>
<!-- JAXB API -->
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>

2. 客户端代码实现

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

public class MyServiceClient {
    public static void main(String[] args) {
        // 1. 初始化Jersey客户端
        Client client = Client.create();
        
        // 2. 构建请求地址(替换为你的服务域名+caseId)
        String caseId = "test-001";
        WebResource webResource = client.resource("http://your-service-domain/case/" + caseId);
        
        // 3. 发送GET请求,获取SOAP响应
        ClientResponse response = webResource.accept("application/xml").get(ClientResponse.class);
        
        if (response.getStatus() != 200) {
            throw new RuntimeException("请求失败,状态码: " + response.getStatus());
        }
        
        try {
            // 4. 解析SOAP信封,定位到myResponse节点
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true); // 必须开启命名空间支持,适配SOAP和业务节点的命名空间
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(response.getEntityInputStream());
            
            // 替换为你的业务命名空间URI和节点名
            Node myResponseNode = doc.getElementsByTagNameNS("http://your-business-namespace", "myResponse").item(0);
            
            // 5. 用JAXB解析为生成的MyResponse类
            JAXBContext jaxbContext = JAXBContext.newInstance(MyResponse.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            MyResponse myResponse = (MyResponse) unmarshaller.unmarshal(myResponseNode);
            
            // 6. 处理响应结果
            System.out.println("获取到的响应内容: " + myResponse.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            response.close();
            client.destroy();
        }
    }
}

方式二:生成SOAP信封JAXB类,优雅解析整个响应

如果希望用JAXB直接解析完整的SOAP信封,可以定义SOAP Envelope和Body的JAXB类,配合业务响应类一起解析,代码更简洁。

1. 定义SOAP相关JAXB类

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

// SOAP信封类,对应<soap:Envelope>
@XmlRootElement(name = "Envelope", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapEnvelope {
    @XmlElement(name = "Body", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapBody body;

    // getter/setter
    public SoapBody getBody() { return body; }
    public void setBody(SoapBody body) { this.body = body; }
}

// SOAP Body类,对应<soap:Body>
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapBody {
    // 替换为你的业务命名空间和节点名
    @XmlElement(name = "myResponse", namespace = "http://your-business-namespace")
    private MyResponse myResponse;

    // getter/setter
    public MyResponse getMyResponse() { return myResponse; }
    public void setMyResponse(MyResponse myResponse) { this.myResponse = myResponse; }
}

2. 简化版客户端代码

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

public class MyServiceClient {
    public static void main(String[] args) {
        Client client = Client.create();
        String caseId = "test-001";
        WebResource webResource = client.resource("http://your-service-domain/case/" + caseId);
        
        try {
            // 直接解析整个SOAP信封
            JAXBContext jaxbContext = JAXBContext.newInstance(SoapEnvelope.class, MyResponse.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            SoapEnvelope envelope = (SoapEnvelope) unmarshaller.unmarshal(webResource.accept("application/xml").getInputStream());
            
            // 提取业务响应对象
            MyResponse myResponse = envelope.getBody().getMyResponse();
            System.out.println("获取到的响应内容: " + myResponse.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.destroy();
        }
    }
}

关键注意事项

  • 命名空间替换:代码中http://your-business-namespace要替换为XSD文件中ns2对应的实际命名空间URI,否则解析会失败。
  • Jersey版本适配:如果你用的是Jersey 2.x(依赖为org.glassfish.jersey.core:jersey-client),API会有差异,需要调整客户端初始化和请求发送的代码。
  • 生成类校验:确保MyResponse类的JAXB注解正确,尤其是命名空间映射,这是解析成功的前提。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:10:15