杰瑞科技汇

java 创建webservice

  1. JAX-WS (Java API for XML Web Services):这是 Java 官方、标准的 WebService 技术,非常成熟、稳定,广泛应用于企业级开发,它默认使用 SOAP 协议。
  2. JAX-RS (Java API for RESTful Web Services):这是创建 RESTful Web 服务的标准 API,它使用 HTTP 协议,通常以 JSON 或 XML 格式传输数据,是目前 Web 开发(特别是前后端分离架构)的主流选择。

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

java 创建webservice-图1
(图片来源网络,侵删)

准备工作:开发环境

你需要一个 Java 开发环境(如 JDK 8 或更高版本)和一个构建工具(如 Maven 或 Gradle),这里我们以 Maven 为例。

使用 JAX-WS (SOAP WebService)

JAX-WS 是 Java EE 的一部分,现在也包含在 Jakarta EE 中,我们不需要引入太多额外的依赖,因为它们通常已经包含在 JDK 或应用服务器(如 Tomcat, JBoss, WebLogic)中。

创建 Maven 项目

在 IDE(如 IntelliJ IDEA 或 Eclipse)中创建一个新的 Maven 项目。

添加 Maven 依赖

虽然 JAX-WS 核心 API 在 JDK 中,但为了方便地开发、测试和发布服务,我们可以使用 javax.xml.ws:jaxws-apicom.sun.xml.ws:jaxws-rt (这是参考实现,用于本地开发和测试)。

java 创建webservice-图2
(图片来源网络,侵删)
<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>jax-ws-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- JAX-WS API -->
        <dependency>
            <groupId>javax.xml.ws</groupId>
            <artifactId>jaxws-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <!-- JAX-WS Reference Implementation (for local development and testing) -->
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-rt</artifactId>
            <version>2.3.3</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 使用 Maven 插件来编译 JAX-WS 注解 -->
            <plugin>
                <groupId>org.jvnet.jax-ws-commons</groupId>
                <artifactId>jaxws-maven-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>wsimport</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

创建 WebService 接口和实现

定义一个服务接口,并用 @WebService 注解标记它。

HelloService.java (接口)

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface HelloService {
    @WebMethod
    String sayHello(@WebParam(name = "name") String name);
    @WebMethod
    int getAge(@WebParam(name = "name") String name);
}

创建这个接口的实现类。

HelloServiceImpl.java (实现)

java 创建webservice-图3
(图片来源网络,侵删)
import javax.jws.WebService;
@WebService(endpointInterface = "com.example.HelloService") // 指定实现的接口
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
    @Override
    public int getAge(String name) {
        // 模拟逻辑
        if ("Alice".equals(name)) {
            return 30;
        }
        return -1; // 表示未知
    }
}

发布 WebService

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

Publisher.java

import javax.xml.ws.Endpoint;
public class Publisher {
    public static void main(String[] args) {
        // 创建服务的实现实例
        HelloService helloService = new HelloServiceImpl();
        // 发布服务
        // 第一个参数是服务的访问地址(Endpoint URL)
        // 第二个参数是服务的实现对象
        String address = "http://localhost:8080/hello";
        Endpoint.publish(address, helloService);
        System.out.println("WebService is published at: " + address);
    }
}

运行和测试

  1. 运行 Publisher.java,你会看到控制台输出 "WebService is published at: http://localhost:8080/hello"。
  2. 打开浏览器,访问 http://localhost:8080/hello?wsdl

    如果看到一个 XML 文件(WSDL 文件),恭喜你,服务发布成功了!WSDL 是 WebService 的描述语言,定义了服务的接口、地址、协议等信息。

  3. 使用客户端测试,你可以使用 IDE 的 WebService 客户端功能,或者使用 wsimport 命令生成客户端代码进行测试。

使用 JAX-RS (RESTful WebService)

JAX-RS 的参考实现是 Jersey,另一个流行的实现是 RESTEasy,这里我们以 Jersey 为例。

创建 Maven 项目

创建一个新的 Maven 项目。

添加 Maven 依赖

我们需要添加 Jersey 的核心依赖以及一个运行它的服务器(如 Grizzly 或嵌入式 Jetty),这里我们使用 Grizzly。

<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>jax-rs-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jersey.version>2.39.1</jersey.version>
    </properties>
    <dependencies>
        <!-- Jersey Core -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-grizzly2-http</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <!-- JSON Support -->
        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-binding</artifactId>
            <version>${jersey.version}</version>
        </dependency>
    </dependencies>
</project>

创建资源类

在 JAX-RS 中,服务被定义为“资源”(Resource),我们创建一个 POJO(普通的 Java 对象)并用 Jersey 的注解来标记它。

UserResource.java

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
// @Path 定义了资源的 URI 路径
@Path("/users")
public class UserResource {
    // 模拟一个数据库
    private List<User> users = new ArrayList<>();
    public UserResource() {
        users.add(new User(1, "Alice"));
        users.add(new User(2, "Bob"));
    }
    // @GET 表示这是一个处理 GET 请求的方法
    // @Path("all") 定义了子路径
    // @Produces 定义了返回的媒体类型
    @GET
    @Path("/all")
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getAllUsers() {
        return users;
    }
    // @Path("{id}") 是一个路径参数
    // @PathParam("id") 用于获取路径中的值
    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUserById(@PathParam("id") int id) {
        User user = users.stream()
                .filter(u -> u.getId() == id)
                .findFirst()
                .orElse(null);
        if (user == null) {
            // 返回 404 Not Found
            return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
        }
        // 返回 200 OK 和用户对象
        return Response.ok(user).build();
    }
    // @POST 表示处理 POST 请求
    // @Consumes 定义了接受的媒体类型
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createUser(User user) {
        // 模拟创建用户
        user.setId(users.size() + 1);
        users.add(user);
        // 返回 201 Created 和新创建的用户
        return Response.status(Response.Status.CREATED).entity(user).build();
    }
    // @PUT 表示处理 PUT 请求
    @PUT
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response updateUser(@PathParam("id") int id, User updatedUser) {
        for (User user : users) {
            if (user.getId() == id) {
                user.setName(updatedUser.getName());
                return Response.ok(user).build();
            }
        }
        return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
    }
    // @DELETE 表示处理 DELETE 请求
    @DELETE
    @Path("{id}")
    public Response deleteUser(@PathParam("id") int id) {
        boolean removed = users.removeIf(u -> u.getId() == id);
        if (removed) {
            return Response.noContent().build(); // 204 No Content
        }
        return Response.status(Response.Status.NOT_FOUND).entity("User not found").build();
    }
}
// 一个简单的 POJO,用于表示用户
class User {
    private int id;
    private String name;
    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; }
}

启动服务器

创建一个主类来启动 Grizzly 服务器并注册我们的资源。

Main.java

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import java.net.URI;
public class Main {
    // 定义服务的基地 URI
    public static final String BASE_URI = "http://localhost:8080/api/";
    public static void main(String[] args) {
        // 创建一个 ResourceConfig 实例,并注册我们的资源类
        ResourceConfig rc = new ResourceConfig().packages("com.example");
        // 创建并启动 Grizzly HTTP 服务器
        HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
        System.out.println("Jersey app started at " + BASE_URI);
        System.out("Hit enter to stop it...");
        try {
            System.in.read();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            server.shutdownNow();
        }
    }
}

运行和测试

  1. 运行 Main.java,你会看到控制台输出 Jersey 服务已启动。

  2. 使用 API 工具(如 Postman, Insomnia)或浏览器进行测试。

    • 获取所有用户:

      • 方法: GET
      • URL: http://localhost:8080/api/users/all
      • 预期响应: [{ "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" }]
    • 根据 ID 获取用户:

      • 方法: GET
      • URL: http://localhost:8080/api/users/1
      • 预期响应: { "id": 1, "name": "Alice" }
    • 创建新用户:

      • 方法: POST
      • URL: http://localhost:8080/api/users
      • Body (raw, JSON): { "name": "Charlie" }
      • 预期响应 (Status 201): { "id": 3, "name": "Charlie" }

总结与对比

特性 JAX-WS (SOAP) JAX-RS (REST)
协议 SOAP (Simple Object Access Protocol) HTTP (GET, POST, PUT, DELETE 等)
数据格式 默认 XML,也可配置其他格式 默认 JSON,也可配置 XML 等
地址风格 基于动作,通常只有一个地址 基于资源,清晰的 URI 结构
标准 Java EE / Jakarta EE 标准 Java EE / Jakarta EE 标准
优点 - 标准化程度高
- 内置安全、事务支持
- 自动生成客户端代理
- 轻量、简单
- 无状态,适合互联网应用
- 更好的缓存和可扩展性
- 与前端框架(如 React, Vue)完美集成
缺点 - 协议复杂,冗余
- 调试困难
- 学习曲线较陡
- 功能相对简单
- 安全、事务需自行实现
适用场景 - 企业内部系统(如 ERP, CRM 集成)
- 对安全性、事务性要求高的场景
- 公开 API
- 移动应用后端
- 前后端分离的 Web 应用

如何选择?

  • 如果你需要与传统的、基于 SOAP 的企业系统(如 .NET, SAP)集成,或者你的项目对事务和安全有极高的标准化要求,选择 JAX-WS
  • 如果你正在构建一个现代化的 Web 应用或 API,特别是需要支持多种客户端(Web, Mobile, 前端框架),并且追求轻量、简单和高效,JAX-RS 是不二之选,JAX-RS 是更主流、更受欢迎的选择。
分享:
扫描分享到社交APP
上一篇
下一篇