杰瑞科技汇

Java WebService教程,从入门到实践怎么学?

Java WebService 完整教程

本教程将带你从零开始,学习如何使用 Java 创建和消费 WebService,我们将使用两种主流的技术栈:

Java WebService教程,从入门到实践怎么学?-图1
(图片来源网络,侵删)
  1. JAX-WS (Java API for XML Web Services):Java 官方标准,历史悠久,广泛支持,适合创建基于 SOAP 协议的 WebService。
  2. JAX-RS (Java API for RESTful Web Services):Java 官方标准,用于创建基于 REST 架构风格的 WebService(通常返回 JSON 或 XML),是目前的主流。

第一部分:核心概念

在开始编码之前,我们先理解几个关键概念。

什么是 WebService?

WebService 是一种跨编程语言、跨操作系统平台的远程调用技术,它允许不同应用通过网络进行交互,就像调用本地方法一样简单。

主要协议:SOAP vs. REST

特性 SOAP (Simple Object Access Protocol) REST (Representational State Transfer)
架构风格 一套严格的协议(Protocol) 一种软件架构风格(Style)
数据格式 强制使用 XML 通常使用 JSON,也支持 XML、HTML 等
通信方式 基于 HTTP/HTTPS,但也可通过 SMTP 等 基于 HTTP/HTTPS
标准性 高度标准化,有 WSDL 描述服务 灵活,没有统一标准,依赖约定
性能 XML 格式冗余,解析较慢,性能较低 JSON 格式轻量,解析快,性能高
安全性 内置安全标准和 WS-* 协议(如 WS-Security) 通常依赖 HTTPS 和 OAuth 等标准
适用场景 企业级应用、金融、电信等对安全性、事务性要求高的场景 移动 App、前后端分离的 Web 应用、公开 API

第二部分:使用 JAX-WS 创建和调用 SOAP WebService

JAX-WS 是 Java EE 的一部分,现在通常包含在 JDK 中,我们将使用 JDK 自带的 wsimport 工具。

步骤 1:创建 WebService 服务端

我们将创建一个简单的 HelloService,它可以根据输入的名字返回问候语。

Java WebService教程,从入门到实践怎么学?-图2
(图片来源网络,侵删)

1 创建一个 Java 项目

  1. 创建一个普通的 Java 项目(JaxWsServer)。
  2. 创建一个服务接口 HelloService.java
// src/com/example/HelloService.java
package com.example;
import javax.jws.WebService;
import javax.jws.WebMethod;
// @WebService 注解将这个类标记为一个 WebService
@WebService
public interface HelloService {
    // @WebMethod 注解将这个方法暴露为 WebService 的一个操作
    @WebMethod
    String sayHello(String name);
}

2 创建服务实现类

// src/com/example/HelloServiceImpl.java
package com.example;
import javax.jws.WebService;
// 实现接口,并指定 serviceName
@WebService(endpointInterface = "com.example.HelloService")
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}

3 发布服务

我们需要一个主类来发布这个服务,我们将它发布在 http://localhost:8080/hello 这个地址上。

Java WebService教程,从入门到实践怎么学?-图3
(图片来源网络,侵删)
// src/com/example/HelloPublisher.java
package com.example;
import javax.xml.ws.Endpoint;
public class HelloPublisher {
    public static void main(String[] args) {
        // 定义服务的发布地址
        String address = "http://localhost:8080/hello";
        // 发布服务
        Endpoint.publish(address, new HelloServiceImpl());
        System.out.println("WebService is published at: " + address);
    }
}

4 运行服务端

运行 HelloPublishermain 方法,你的 SOAP WebService 已经启动并运行在 http://localhost:8080/hello

你可以在浏览器中访问这个地址,通常会看到一个页面,提示你这是一个 WSDL 文件,WSDL (Web Services Description Language) 是用来描述 WebService 的 XML 文件。

步骤 2:创建 WebService 客户端

我们创建另一个项目来调用刚刚发布的服务,我们将使用 JDK 自带的 wsimport 工具来生成客户端代码。

1 使用 wsimport 生成客户端代码

打开命令行(CMD 或 PowerShell),切换到你的客户端项目目录(JaxWsClient),然后执行以下命令:

wsimport -p com.example.client -keep http://localhost:8080/hello?wsdl

命令解释:

  • wsimport: JDK 自带的工具。
  • -p com.example.client: 指定生成的客户端代码的包名。
  • -keep: 保留生成的源文件,方便查看。
  • http://localhost:8080/hello?wsdl: 服务端的 WSDL 地址。

执行后,会在 com.example.client 包下生成一堆 Java 文件(包括接口、服务、模型类等)。

2 编写客户端调用代码

在客户端项目中创建一个 HelloClient.java

// src/com/example/client/HelloClient.java
package com.example.client;
public class HelloClient {
    public static void main(String[] args) {
        // 1. 创建服务视图 (Service)
        HelloService_Service service = new HelloService_Service();
        // 2. 获取服务端点 (Port),即服务的实现类
        HelloService helloPort = service.getHelloServicePort();
        // 3. 像调用本地方法一样调用远程方法
        String response = helloPort.sayHello("WebService World");
        // 4. 打印结果
        System.out.println("Response from server: " + response);
    }
}

3 运行客户端

运行 HelloClientmain 方法,如果一切正常,你将看到输出:

Response from server: Hello, WebService World!

至此,一个完整的 JAX-WS 开发流程就完成了。


第三部分:使用 JAX-RS (RESTful WebService)

RESTful WebService 是目前的主流,我们使用 Jersey 作为 JAX-RS 的参考实现(这也是许多教程选择它的原因),它更简单、更灵活。

步骤 1:环境准备

你需要添加 Jersey 的核心依赖,如果你使用 Maven,在 pom.xml 中添加:

<dependencies>
    <!-- Jersey 核心依赖 -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-grizzly2-http</artifactId>
        <version>2.39</version> <!-- 使用最新稳定版本 -->
    </dependency>
    <!-- 支持 JSON -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.39</version>
    </dependency>
</dependencies>

步骤 2:创建 RESTful 服务端

我们将创建一个管理用户信息的 RESTful API。

1 创建资源类

资源类是 RESTful 服务的核心,每个方法通常对应一个 HTTP 请求。

// src/com/example/UserResource.java
package com.example;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
// @Path 注解定义了资源的基 URI 路径
@Path("/users")
public class UserResource {
    // 模拟一个数据库
    private static List<User> users = new ArrayList<>();
    static {
        users.add(new User(1, "Alice"));
        users.add(new User(2, "Bob"));
    }
    // @GET: 处理 HTTP GET 请求
    // @Produces: 指定返回的媒体类型,这里是 JSON
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getAllUsers() {
        return users;
    }
    // @Path: 可以在 @Path 下定义子路径
    // @PathParam: 从路径中获取参数
    @GET
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public getUserById(@PathParam("id") int id) {
        return users.stream()
                .filter(user -> user.getId() == id)
                .findFirst()
                .orElse(null); // 如果找不到,返回 null
    }
    // @POST: 处理 HTTP POST 请求
    // @Consumes: 指定接收的请求体媒体类型
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public User createUser(User user) {
        user.setId(users.size() + 1); // 简单生成 ID
        users.add(user);
        return user;
    }
}
// 一个简单的 POJO (Plain Old Java Object)
class User {
    private int id;
    private String name;
    // 构造函数、Getter 和 Setter 是必须的,Jackson 依赖它们
    public User() {}
    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
    // Getters and Setters
    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; }
}

2 创建启动类

// src/com/example/MyApplication.java
package com.example;
import org.glassfish.jersey.server.ResourceConfig;
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        // 注册资源类
        register(UserResource.class);
    }
}

3 创建主类来启动服务器

// src/com/example/ServerMain.java
package com.example;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import java.net.URI;
public class ServerMain {
    public static final String BASE_URI = "http://localhost:8080/";
    public static void main(String[] args) {
        // 创建 ResourceConfig 实例
        final ResourceConfig rc = new MyApplication();
        // 创建并启动 Grizzly HTTP 服务器
        HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
        System.out.println("Server started at " + BASE_URI);
        try {
            // 阻塞主线程,保持服务器运行
            System.in.read();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            server.shutdownNow();
        }
    }
}

4 运行服务端

运行 ServerMainmain 方法,服务器启动在 http://localhost:8080/

你可以使用 Postman 或浏览器(对于 GET 请求)来测试 API:

  • GET http://localhost:8080/users -> 获取所有用户
  • GET http://localhost:8080/users/1 -> 获取 ID 为 1 的用户
  • POST http://localhost:8080/users -> 创建新用户,请求体为 {"name": "Charlie"}

步骤 3:创建 RESTful 客户端

Jersey 也提供了强大的客户端 API。

1 创建客户端代码

// src/com/example/client/RestClient.java
package com.example.client;
import com.example.User;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientResponse;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
public class RestClient {
    public static void main(String[] args) {
        // 1. 创建客户端
        Client client = ClientBuilder.newClient(new ClientConfig());
        // 2. 定义服务器的根地址
        WebTarget target = client.target("http://localhost:8080");
        // --- 测试 GET /users ---
        System.out.println("--- Testing GET /users ---");
        WebTarget allUsersTarget = target.path("users");
        List<User> allUsers = allUsersTarget.request(MediaType.APPLICATION_JSON).get(List.class);
        allUsers.forEach(System.out::println);
        // --- 测试 GET /users/1 ---
        System.out.println("\n--- Testing GET /users/1 ---");
        WebTarget userTarget = target.path("users").path("1");
        User user = userTarget.request(MediaType.APPLICATION_JSON).get(User.class);
        System.out.println("Found user: " + user);
        // --- 测试 POST /users ---
        System.out.println("\n--- Testing POST /users ---");
        WebTarget createUserTarget = target.path("users");
        User newUser = new User();
        // 注意:ID 通常由服务器生成,客户端可以不设置或设为 0
        newUser.setName("David"); 
        // 发送 POST 请求,并接收响应
        Response postResponse = createUserTarget.request()
                .post(Entity.entity(newUser, MediaType.APPLICATION_JSON));
        if (postResponse.getStatus() == Response.Status.CREATED.getStatusCode()) {
            User createdUser = postResponse.readEntity(User.class);
            System.out.println("Created user: " + createdUser);
        } else {
            System.out.println("Failed to create user. Status: " + postResponse.getStatus());
        }
        client.close();
    }
}

2 运行客户端

运行 RestClientmain 方法,它会依次调用服务端的 API 并打印结果。


总结与建议

特性 JAX-WS (SOAP) JAX-RS (REST)
适用场景 企业内部系统、需要严格契约、高安全性要求 公开 API、移动后端、前后端分离项目
学习曲线 较陡峭,涉及 WSDL、SOAP 协议细节 较平缓,概念简单,易于上手
开发效率 较低,代码生成步骤多 较高,注解驱动,开发迅速
社区与生态 成熟,但在新项目中较少使用 极其活跃,是当前 Web 开发的主流

给你的建议:

  • 如果你是初学者直接学习 JAX-RS (RESTful),这是当前业界的事实标准,应用范围更广,学习成果更有价值。
  • 如果你需要与遗留系统集成:某些旧系统可能只提供 SOAP 接口,这时你需要了解 JAX-WS。
  • 如果你需要最高级别的安全和事务支持:SOAP 的 WS-* 标准提供了非常完善的企业级解决方案,而 REST 的实现通常需要自己组合多种技术。

希望这份详细的教程能帮助你快速入门 Java WebService 开发!

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