杰瑞科技汇

Java如何高效解析WebService?

第一部分:解析 SOAP WebService (基于 XML)

SOAP (Simple Object Access Protocol) 是一种基于 XML 的协议,解析 SOAP WebService 通常意味着:

Java如何高效解析WebService?-图1
(图片来源网络,侵删)
  1. 生成客户端代码:根据服务的 WSDL (Web Services Description Language) 文件,自动生成客户端代理类。
  2. 调用服务:通过生成的代理类,像调用本地方法一样远程调用 WebService。
  3. 处理响应:接收并解析服务器返回的 SOAP 消息(也是一个 XML)。

核心工具

  1. JDK 自带 wsimport:这是最常用、最标准的方式,它是一个命令行工具,用于根据 WSDL 文件生成 JAX-WS (Java API for XML Web Services) 客户端代码。
  2. 框架集成:如 Spring-WS,它提供了更灵活的编程模型,但底层原理与 wsimport 类似。
  3. 第三方库:如 Apache CXF,功能强大,支持更多高级特性。

步骤详解 (以 wsimport 为例)

假设我们要调用一个公共的天气查询 WebService,它的 WSDL 地址是:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl

第 1 步:获取 WSDL 文件

确保你有 WebService 的 WSDL 文件地址,这是一个 .wsdl 文件,描述了服务的所有接口、方法、参数和返回类型。

第 2 步:使用 wsimport 生成客户端代码

打开命令行(CMD 或 PowerShell),执行以下命令:

# -p: 指定生成的Java包名
# -d: 指定生成.class文件的存放目录
# -keep: 生成.java源文件,方便查看
wsimport -p com.example.weather.client -d ./src/main/java -keep http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl

执行后,wsimport 会在 com.example.weather.client 包下生成一系列 Java 文件,包括:

Java如何高效解析WebService?-图2
(图片来源网络,侵删)
  • WeatherWS.java:服务接口。
  • WeatherWSImplService.java:服务工厂类。
  • getWeather.javagetWeatherResponse.java:对应 getWeather 方法的请求和响应对象。
  • 以及其他一些辅助类(如 ObjectFactory.java, package-info.java 等)。

第 3 步:在 Java 代码中调用服务

现在你可以在你的 Java 项目中使用这些生成的类了。

package com.example.weather;
import com.example.weather.client.WeatherWS;
import com.example.weather.client.WeatherWSImplService;
import com.example.weather.client.getWeather;
import com.example.weather.client.getWeatherResponse;
public class WeatherServiceClient {
    public static void main(String[] args) {
        // 1. 创建服务工厂
        WeatherWSImplService service = new WeatherWSImplService();
        // 2. 获取服务端点接口
        WeatherWS weatherWS = service.getWeatherWSImplPort();
        // 3. 创建请求对象,并设置参数
        // getWeather 是请求类,cityName 是请求参数
        getWeather request = new getWeather();
        request.setCityName("北京"); // 设置要查询的城市
        // 4. 调用远程方法,获取响应对象
        getWeatherResponse response = weatherWS.getWeather(request);
        // 5. 从响应对象中解析数据
        // response.getgetWeatherResult() 返回的是一个包含XML数据的字符串
        String weatherXmlData = response.getgetWeatherResult();
        System.out.println("从WebService获取到的原始XML数据:");
        System.out.println(weatherXmlData);
        // 6. 解析XML数据 (这是"解析"的关键步骤)
        // 这里简单地将XML按行分割,实际项目中应使用DOM、SAX或JAXB等解析器
        if (weatherXmlData != null && !weatherXmlData.contains("查询结果为空")) {
            String[] lines = weatherXmlData.split("\n");
            for (String line : lines) {
                System.out.println(line.trim());
            }
        } else {
            System.out.println("未能获取到天气数据。");
        }
    }
}

"解析" 的进一步说明:

在上面的例子中,response.getgetWeatherResult() 返回的是一个 XML 字符串,真正的 "解析" 是指从这个 XML 字符串中提取出有用的信息。

  • 手动解析 (不推荐):使用 String.split() 或正则表达式,简单、脆弱,容易因XML格式变化而失效。
  • 标准解析方式
    • DOM (Document Object Model):将整个XML读入内存,解析成一个树形结构,适合小型XML文件,查询方便但占用内存大。
    • SAX (Simple API for XML):事件驱动的解析模型,逐行读取XML,遇到元素开始、结束等事件时触发回调方法,适合大型XML文件,内存占用小,但编程复杂。
    • JAXB (Java Architecture for XML Binding)最推荐的方式,它能自动将XML元素/属性与Java对象进行绑定,你需要根据返回的XML结构,创建对应的Java Bean(POJO),JAXB.unmarshal() 就能直接将XML字符串转换成Java对象,非常方便。

第二部分:解析 RESTful WebService (通常返回 JSON)

RESTful WebService 遵循 REST 架构风格,通常通过 HTTP 协议(GET, POST, PUT, DELETE)以 JSON (JavaScript Object Notation) 格式交换数据,解析它主要是发送 HTTP 请求并处理返回的 JSON 响应。

Java如何高效解析WebService?-图3
(图片来源网络,侵删)

核心工具

  1. JDK 11+ 的 HttpClient:官方推荐,功能强大,现代。
  2. Apache HttpComponents:非常流行、稳定、功能全面的 HTTP 客户端库。
  3. OkHttp:另一个流行的第三方 HTTP 客户端,以其高效和易用性著称。
  4. Jackson / Gson:用于将 JSON 字符串解析成 Java 对象,是事实上的标准。

步骤详解 (以 HttpClient + Jackson 为例)

假设我们要调用一个公共的 JSONPlaceholder API 来获取一个用户信息:https://jsonplaceholder.typicode.com/users/1

第 1 步:添加依赖

如果你使用 Maven,在 pom.xml 中添加 Jackson 依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- 使用最新版本 -->
</dependency>

第 2 步:创建与 JSON 结构对应的 Java 类 (POJO)

这是解析 JSON 的关键,你需要根据返回的 JSON 结构,创建一个或多个 Java 类来映射它。

对于 https://jsonplaceholder.typicode.com/users/1 的返回:

{
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
    }
  },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
  }
}

你需要创建对应的 Java 类:

// User.java
package com.example.rest.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true) // 忽略JSON中存在但Java类中没有的属性
public class User {
    private int id;
    private String name;
    private String username;
    private String email;
    private Address address;
    private String phone;
    private String website;
    private Company company;
    // Getters and Setters (省略...)
    // 可以使用 Lombok @Data 注解自动生成
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    // ... 其他getter和setter
}
// Address.java
package com.example.rest.model;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Address {
    private String street;
    private String suite;
    private String city;
    private String zipcode;
    private Geo geo;
    // Getters and Setters (省略...)
}
// Geo.java
package com.example.rest.model;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Geo {
    private String lat;
    private String lng;
    // Getters and Setters (省略...)
}
// Company.java
package com.example.rest.model;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Company {
    private String name;
    private String catchPhrase;
    private String bs;
    // Getters and Setters (省略...)
}

第 3 步:发送 HTTP 请求并解析 JSON 响应

package com.example.rest;
import com.example.rest.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class RestClient {
    public static void main(String[] args) {
        // 1. 创建 HttpClient
        HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2)
                .connectTimeout(Duration.ofSeconds(10))
                .build();
        // 2. 创建 HttpRequest
        HttpRequest request = HttpRequest.newBuilder()
                .GET()
                .uri(URI.create("https://jsonplaceholder.typicode.com/users/1"))
                .header("Accept", "application/json")
                .build();
        try {
            // 3. 发送请求并获取响应
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            // 4. 检查响应状态码
            if (response.statusCode() == 200) {
                System.out.println("请求成功,响应体:");
                System.out.println(response.body());
                // 5. 使用 Jackson 解析 JSON 字符串为 Java 对象
                ObjectMapper objectMapper = new ObjectMapper();
                User user = objectMapper.readValue(response.body(), User.class);
                // 6. 使用解析后的对象
                System.out.println("\n解析后的Java对象信息:");
                System.out.println("ID: " + user.getId());
                System.out.println("Name: " + user.getName());
                System.out.println("Email: " + user.getEmail());
                System.out.println("City: " + user.getAddress().getCity());
            } else {
                System.err.println("请求失败,状态码: " + response.statusCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

总结与对比

特性 SOAP WebService RESTful WebService
协议 严格基于 XML,通过 SOAP 信封传输 基于 HTTP (GET/POST/PUT/DELETE),数据格式通常是 JSON
核心工具 wsimport, JAX-WS, Apache CXF HttpClient, OkHttp, Jackson, Gson
解析过程 生成客户端代码
2. 调用方法,获取XML响应
3. 用DOM/SAX/JAXB解析XML
手动构建HTTP请求
2. 发送请求,获取JSON响应
3. 用Jackson/Gson等库将JSON反序列化为Java对象
优点 标准化、安全(内置WS-Security)、跨语言、工具成熟 轻量级、简单(基于HTTP)、性能好(JSON比XML解析快)、易于与Web前端集成
缺点 协议复杂、冗余(XML开销大)、性能相对较低 无统一标准,安全性需自行实现(如HTTPS、OAuth)
适用场景 企业级应用、金融、电信等对安全性和事务性要求高的场景 移动应用、前后端分离项目、微服务、公开API

如何选择?

  • 如果你的服务是遗留系统,或者你处于一个对标准化和安全有严格要求的行业(如银行、政府),那么你很可能需要处理 SOAP WebService。
  • 对于所有新的 Web 开发项目,特别是前后端分离架构,RESTful WebService 几乎是默认选择,因为它更简单、更灵活、更高效。

希望这份详细的指南能帮助你理解如何在 Java 中解析不同类型的 WebService!

分享:
扫描分享到社交APP
上一篇
下一篇