如何通过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
相关产品推荐
相关产品推荐

