杰瑞科技汇

Java WebService如何快速生成?

  1. JAX-WS (Java API for XML Web Services):这是 Java 官方、成熟的 WebService 标准,它非常稳定,与 Java EE (Jakarta EE) 深度集成,特别适合构建传统的、基于 SOAP 协议的 WebService,对于新项目,如果必须使用 SOAP,JAX-WS 是首选。
  2. JAX-RS (Java API for RESTful Web Services):这是用于构建 RESTful 风格 Web 服务的标准,RESTful 服务通常使用 HTTP 协议,以 JSON 或 XML 作为数据格式,轻量、简单、易于与前端(特别是 JavaScript)集成,绝大多数新的 Web 服务都采用 RESTful 风格。

下面我将分别介绍如何使用这两种技术来创建 WebService。

Java WebService如何快速生成?-图1
(图片来源网络,侵删)

准备工作:开发环境

  1. JDK: Java Development Kit (版本 8 或更高版本)。
  2. 构建工具: Maven 或 Gradle,这里我们以 Maven 为例,因为它非常普及且配置简单。
  3. IDE: IntelliJ IDEA 或 Eclipse。

使用 JAX-WS (SOAP WebService)

JAX-WS 的核心思想是:通过一个 Java 接口来定义服务的契约(WSDL),然后由 JDK 或框架(如 Apache CXF)帮你自动实现这个接口并发布成 WebService。

步骤 1:创建 Maven 项目

在 IDE 中创建一个新的 Maven 项目,pom.xml 文件基本可以保持为默认的 maven-archetype-quickstart

步骤 2:编写服务接口和实现类

这是 JAX-WS 的核心,你需要定义一个 Java 接口,并用 @WebService 注解来标记它。

服务接口 (src/main/java/com/example/HelloService.java)

Java WebService如何快速生成?-图2
(图片来源网络,侵删)
package com.example;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
 * 使用 @WebService 注解标记这是一个 WebService 接口
 * name: 服务名
 * targetNamespace: 命名空间,通常使用反向域名
 */
@WebService(name = "HelloService", targetNamespace = "http://example.com/")
public interface HelloService {
    /**
     * 使用 @WebMethod 注解标记这是一个 WebService 方法
     * operationName: 方法的公开名称
     */
    @WebMethod(operationName = "sayHello")
    String sayHello(@WebParam(name = "name") String name);
}

服务实现类 (src/main/java/com/example/HelloServiceImpl.java)

package com.example;
import javax.jws.WebService;
/**
 * 使用 @WebService 注解实现接口
 * endpointInterface: 指明实现的是哪个接口
 */
@WebService(endpointInterface = "com.example.HelloService")
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return "你好, " + name + "! 欢迎使用 JAX-WS WebService.";
    }
}

步骤 3:发布 WebService

我们可以使用 JDK 内置的 Endpoint 类来快速发布服务,这非常适合开发和测试。

创建发布类 (src/main/java/com/example/WebServicePublisher.java)

package com.example;
import javax.xml.ws.Endpoint;
/**
 * WebService 发布器
 */
public class WebServicePublisher {
    public static void main(String[] args) {
        // 定义服务的访问地址
        String address = "http://localhost:8888/ws/hello";
        // 发布服务
        // 参数1: 服务的访问地址
        // 参数2: 服务的实现类实例
        Endpoint.publish(address, new HelloServiceImpl());
        System.out.println("WebService 发布成功!");
        System.out.println("访问地址: " + address + "?wsdl");
        System.out.println("你可以使用浏览器或 SOAP UI 工具访问这个地址来查看 WSDL 文档。");
    }
}

步骤 4:运行和测试

  1. 运行:直接运行 WebServicePublishermain 方法。

    Java WebService如何快速生成?-图3
    (图片来源网络,侵删)
  2. 验证 WSDL:打开浏览器,访问 http://localhost:8888/ws/hello?wsdl,如果看到一个 XML 文件(WSDL 定义),说明服务发布成功。

  3. 客户端测试

    • 使用 JDK 自带的 wsimport 工具

      # 在命令行中执行,根据你的 WSDL 地址生成客户端代码
      wsimport -keep -p com.example.client http://localhost:8888/ws/hello?wsdl

      这会在 com.example.client 包下生成一堆 Java 文件(接口、实现类等),然后你可以写一个简单的客户端来调用。

    • 使用 SOAP UI:这是一个专业的 SOAP 测试工具,创建一个新的 SOAP Project,输入 WSDL 地址,它会自动解析出所有可用的方法,你可以直接填写参数并发送请求来测试。


使用 JAX-RS (RESTful WebService)

JAX-RS 是一个标准,不同的实现(框架)提供了不同的功能,最流行、功能最强大的实现是 JerseyRESTEasy,这里我们以 Jersey 为例,因为它是 JAX-RS 的参考实现。

步骤 1:创建 Maven 项目

创建一个新的 Maven 项目,并在 pom.xml 中添加 Jersey 的依赖。

pom.xml

<dependencies>
    <!-- Jersey 核心依赖 -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-grizzly2-http</artifactId>
        <!-- 使用 2.35 版本,与 Jakarta EE 9+ 兼容 -->
        <version>2.35</version>
    </dependency>
    <!-- 支持 JSON 格式 (需要 Jackson) -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-binding</artifactId>
        <version>2.35</version>
    </dependency>
</dependencies>

步骤 2:编写资源类

在 RESTful 架构中,每个 URL 路径都对应一个“资源”,资源由一个 Java 类(Resource Class)来表示,类中的公共方法就是处理 HTTP 请求的“方法”。

资源类 (src/main/java/com/example/Resource.java)

package com.example;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
 * @Path: 定义资源的基本路径
 * @Produces: 定义该方法能产生的媒体类型,这里是 JSON
 * @Consumes: 定义该方法能接受的媒体类型,这里是 JSON
 */
@Path("users")
public class Resource {
    // GET 请求: http://localhost:8080/api/users/123
    @GET
    @Path("/{userId}")
    @Produces(MediaType.APPLICATION_JSON)
    public User getUser(@PathParam("userId") int userId) {
        System.out.println("收到 GET 请求,用户ID: " + userId);
        // 模拟从数据库获取用户
        User user = new User();
        user.setId(userId);
        user.setName("张三");
        user.setEmail("zhangsan@example.com");
        return user;
    }
    // POST 请求: http://localhost:8080/api/users
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createUser(User user) {
        System.out.println("收到 POST 请求,新用户: " + user.getName());
        // 模拟将用户保存到数据库
        // ... save logic ...
        // 返回一个 201 Created 响应,并包含新创建资源的路径
        return Response.status(Response.Status.CREATED)
                       .entity("用户创建成功,ID: " + user.getId())
                       .build();
    }
}
// 一个简单的 POJO (Plain Old Java Object),用于表示数据
class User {
    private int id;
    private String name;
    private String email;
    // 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; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

步骤 3:配置和启动 HTTP 服务器

Jersey 本身不包含 HTTP 服务器,所以我们需要一个像 Grizzly 或 Jetty 这样的服务器来托管我们的应用。

启动类 (src/main/java/com/example/Main.java)

package com.example;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import java.io.IOException;
import java.net.URI;
/**
 * Jersey 服务器启动类
 */
public class Main {
    // 定义基础 URI
    public static final String BASE_URI = "http://localhost:8080/api/";
    public static void main(String[] args) {
        // 1. 创建一个 ResourceConfig 实例,并注册我们的资源类
        // 扫描 com.example 包下的所有资源
        final ResourceConfig rc = new ResourceConfig().packages("com.example");
        // 2. 创建 Grizzly HTTP 服务器
        final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
        try {
            // 3. 启动服务器
            System.out.println("Jersey 应用启动,访问地址: " + BASE_URI);
            server.start();
            // 保持服务器运行
            Thread.currentThread().join();
        } catch (IOException | InterruptedException e) {
            System.err.println("服务器启动失败: " + e.getMessage());
        }
    }
}

步骤 4:运行和测试

  1. 运行:直接运行 Main 类的 main 方法。
  2. 测试
    • 浏览器测试
      • GET 请求:在浏览器地址栏输入 http://localhost:8080/api/users/123,浏览器会显示一个 JSON 字符串:{"id":123,"name":"张三","email":"zhangsan@example.com"}
    • 命令行工具测试 (使用 curl)
      • GET 请求:
        curl http://localhost:8080/api/users/123
      • POST 请求 (需要发送 JSON 数据):
        curl -X POST -H "Content-Type: application/json" -d '{"id":0,"name":"李四","email":"lisi@example.com"}' http://localhost:8080/api/users

        你会看到服务器返回 用户创建成功,ID: 0


总结与对比

特性 JAX-WS (SOAP) JAX-RS (RESTful)
协议 SOAP (Simple Object Access Protocol) HTTP (GET, POST, PUT, DELETE 等)
数据格式 XML (默认),也支持 JSON JSON (主流),也支持 XML
架构风格 面向服务,有严格的契约 (WSDL) 面向资源,无状态
优点 - 标准化,跨语言能力强
- 内置安全、事务等机制
- 契约驱动,易于集成
- 轻量,简单,性能好
- 无需 XML 解析,直接使用 HTTP
- 非常适合前后端分离的 Web 应用
缺点 - 协议复杂,笨重
- 学习曲线稍陡
- 不适合浏览器直接调用
- 无统一标准,实现方式多样
- 安全性需要自己实现
适用场景 - 企业级应用集成 (B2B)
- 需要强类型和严格契约的系统
- 金融、电信等传统行业
- 移动应用后端 API
- 现代化的 Web 应用 (前后端分离)
- 微服务架构

如何选择?

  • 如果你的项目需要与传统的、基于 SOAP 的企业系统(如 .NET 服务)集成,或者你需要一个强契约、高安全性的服务,选择 JAX-WS
  • 如果你在构建一个新的 Web 应用,特别是需要为移动端或前端提供 API,或者你倾向于轻量级、易于开发和维护的架构,强烈推荐选择 JAX-RS (RESTful),RESTful 已经成为 Web 服务开发的主流。
分享:
扫描分享到社交APP
上一篇
下一篇