上一篇
java怎么调用wcf
- 后端开发
- 2025-08-07
- 4
在Java中调用WCF可通过JAX-WS规范实现:添加Web服务引用生成客户端桩代码,配置端点地址与绑定参数,通过SOAP协议发送XML请求并接收响应,需引入相应依赖库
以下是关于 Java 调用 WCF 服务的完整技术实现方案,涵盖原理、工具链、代码示例及常见问题解决方案:
核心概念解析
1 WCF 的本质特征
特性 | 说明 |
---|---|
跨平台性 | 基于 SOAP/HTTP 标准协议栈,天然支持异构系统交互 |
服务端形态 | 可发布为 .NET Remoting/TCP/HTTP/NamedPipes 等多种通信模式 |
元数据暴露 | 通过 ?wsdl 端点提供 WSDL 描述文件,供客户端自动生成调用代码 |
数据契约优先 | 强类型校验机制,需严格匹配服务端定义的数据结构和命名空间 |
2 Java 调用的核心挑战
协议转换:将 .NET 特有的二进制编码转换为 Java 可识别的文本格式(SOAP XML)
类型映射:复杂对象(如 DataTable、自定义类)需手动构建 Java POJO 对应关系
上下文维护:会话状态(Session)、事务边界等需显式控制
实施步骤详解
1 前置条件准备
序号 | 项目 | 具体要求 |
---|---|---|
1 | 有效 WSDL 地址 | 确保可通过浏览器访问 http://<server>/MyService.svc?wsdl |
2 | JDK 版本 | 推荐 Java 8+(支持 JAX-WS 2.x 规范) |
3 | 构建工具 | Maven/Gradle 用于管理依赖项 |
4 | IDE 插件 | IntelliJ IDEA/Eclipse + Web Services Explorer 插件辅助调试 |
2 关键步骤分解
▶ Step 1: 获取并分析 WSDL 文档
curl "http://localhost:8733/Design_Time_Addresses/MyService/Service1.svc?wsdl" -o service.wsdl
重点检查项:
<wsdl:types>
节点确认数据类型定义<wsdl:binding>
查看传输协议(默认 HTTP/SOAP)<wsdl:service>
提取端口地址池
▶ Step 2: 使用 wsimport 生成客户端桩代码
wsimport -keep -p com.example.client -b customBinding.xml -XautoNameResolution http://localhost:8733/Design_Time_Addresses/MyService/Service1.svc?wsdl
参数说明:
| 参数 | 作用 |
|——————–|———————————————————————-|
| -keep
| 保留原始 WSDL 文件 |
| -p <package>
| 指定生成类的包路径 |
| -b <bindingFile>
| 自定义绑定文件(可选) |
| -XautoNameRes
| 自动解决名称冲突(推荐启用) |
▶ Step 3: Maven 依赖配置(pom.xml)
<dependencies> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-transport-http</artifactId> <version>1.7.9</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> </dependency> </dependencies>
▶ Step 4: 编写调用代码(典型示例)
import javax.xml.ws.BindingProvider; import com.example.client.Service1; import com.example.client.Service1Soap; public class WcfClient { public static void main(String[] args) { try { // 1. 创建服务实例 Service1 service = new Service1(); // 2. 获取SOAP端口(关键步骤) Service1Soap port = service.getBasicHttpBindingIService1(); // 3. 强制类型转换获取底层HandlerResolver BindingProvider bp = (BindingProvider) port; bp.getRequestContext().put("SOAPAction", "http://tempuri.org/IService1/MethodName"); // 4. 构造请求参数(注意类型匹配) ParameterType parameter = new ParameterType(); parameter.setFieldA("TestValue"); // 5. 执行方法调用 ReturnType result = port.methodName(parameter); System.out.println("Response: " + result.getResultField()); } catch (Exception e) { e.printStackTrace(); // 特殊处理:捕获SOAPFaultDetail元素中的错误详情 if (e instanceof javax.xml.ws.soap.SOAPFaultException) { System.err.println("SOAP Fault Code: " + ((javax.xml.ws.soap.SOAPFaultException)e).getFault().getFaultCode()); } } } }
️ 关键注意事项:
- 命名空间一致性:生成的 SEI(Service Endpoint Interface)必须与 WSDL 完全一致
- 集合类型处理:ArrayOfXXX 类需使用 List