杰瑞科技汇

Java开发WebService,如何快速入门?

开发 Java WebService 主要有两种主流技术栈:

Java开发WebService,如何快速入门?-图1
(图片来源网络,侵删)
  1. JAX-WS (Java API for XML Web Services):这是 Java 标准的、传统的 WebService 开发技术,基于 SOAP 协议,它非常成熟,广泛用于企业级应用,特别是需要高安全性、事务性和复杂交互的场景。
  2. JAX-RS (Java API for RESTful Web Services):这是用于开发 RESTful 风格 WebService 的 Java API,通常基于 HTTP 协议和 JSON 数据格式,它更轻量、更简单、更易于与前端(特别是移动端和单页应用)集成,是目前非常流行的选择。

下面我将分别对这两种技术进行详细说明,并提供完整的代码示例。


使用 JAX-WS 开发 SOAP WebService

SOAP (Simple Object Access Protocol) 是一个基于 XML 的协议,它非常严格和重量级,但功能强大,支持 WS-Security、WS-Addressing 等标准。

核心概念

  • SEI (Service Endpoint Interface):服务端点接口,一个 Java 接口,定义了 WebService 提供的方法。
  • SIB (Service Implementation Bean):服务实现 Bean,一个 Java 类,实现了 SEI 接口,包含了具体的业务逻辑。
  • WSDL (Web Services Description Language):Web服务描述语言,一个 XML 文件,用于描述WebService的功能、接口、协议绑定等信息,客户端通过 WSDL 来了解如何调用服务。
  • Publisher:发布者,负责将 SIB 发布成一个可以通过网络访问的 WebService。

开发步骤(以原生 JDK 自带的 javax.xml.ws API 为例)

步骤 1:创建 SEI (接口)

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

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService 注解将这个接口标记为 WebService 接口
@WebService
// @SOAPBinding(style = SOAPBinding.Style.RPC) 可以指定为 RPC 风格,默认是 DOCUMENT
public interface HelloWorld {
    // @WebMethod 注解将这个方法标记为 WebService 的操作
    @WebMethod
    String sayHello(String name);
}

步骤 2:创建 SIB (实现类)

创建一个类来实现上面的接口。

Java开发WebService,如何快速入门?-图2
(图片来源网络,侵删)
import javax.jws.WebService;
// serviceName 指定服务的名称,endpointInterface 指定它实现的接口
@WebService(serviceName = "HelloWorldService", endpointInterface = "com.example.jaxws.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}

步骤 3:发布 WebService

使用 Endpoint 类来发布服务,它需要一个 URL 地址和一个 SIB 实例。

import javax.xml.ws.Endpoint;
public class Publisher {
    public static void main(String[] args) {
        // 定义服务的发布地址
        String address = "http://localhost:8080/helloWorld";
        // 创建 SIB 实例
        HelloWorld helloWorld = new HelloWorldImpl();
        // 发布服务
        Endpoint.publish(address, helloWorld);
        System.out.println("WebService is published at: " + address);
    }
}

步骤 4:测试

  1. 运行 Publisher:启动 Publishermain 方法。

  2. 访问 WSDL:在浏览器中访问 http://localhost:8080/helloWorld?wsdl,如果能看到 XML 内容,说明服务发布成功。

  3. 客户端调用

    Java开发WebService,如何快速入门?-图3
    (图片来源网络,侵删)
    • 使用 JDK 自带的 wsimport 工具 在命令行中执行:

      wsimport -s ./src -p com.example.jaxws.client http://localhost:8080/helloWorld?wsdl

      这会生成客户端所需的 Java 类(SEI 的实现类、Service 类等)。

    • 编写客户端代码

      import com.example.jaxws.client.HelloWorld;
      import com.example.jaxws.client.HelloWorldService;
      public class JAXWSClient {
          public static void main(String[] args) {
              // 创建 Service 实例,WSDL 的地址
              HelloWorldService service = new HelloWorldService();
              // 获取 Port (SEI 的实现对象)
              HelloWorld helloWorld = service.getHelloWorldPort();
              // 调用方法
              String response = helloWorld.sayHello("JAX-WS Client");
              System.out.println(response);
          }
      }

使用 JAX-RS 开发 RESTful WebService

REST (Representational State Transfer) 是一种软件架构风格,而不是一个标准,它更简单,直接使用 HTTP 协议的方法(GET, POST, PUT, DELETE)来操作资源。

核心概念

  • 资源:在 REST 中,一切皆资源,用户、订单、产品等。
  • URI (Uniform Resource Identifier):用于唯一标识一个资源,如 /users/123
  • HTTP 方法
    • GET:获取资源。
    • POST:创建新资源。
    • PUT:更新资源(全量)。
    • DELETE:删除资源。
  • 数据格式:通常使用 JSON 或 XML,JSON 更为流行。

开发步骤(以流行的框架 Jersey 为例)

Jersey 是 JAX-RS 的一个参考实现,也是目前最流行的实现之一。

步骤 1:准备环境(Maven 依赖)

在你的 pom.xml 文件中添加 Jersey 的核心依赖。

<dependencies>
    <!-- Jersey 核心依赖 -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-grizzly2-http</artifactId>
        <!-- 使用 2.35 版本,请根据需要调整 -->
        <version>2.35</version>
    </dependency>
    <!-- 支持 JSON -->
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.35</version>
    </dependency>
</dependencies>

步骤 2:创建资源类

使用 @Path 注解来标记一个类作为资源类,使用 @GET, @POST, @PUT, @DELETE 等注解来标记方法。

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 static List<User> userDatabase = new ArrayList<>();
    // @GET 表示这是一个处理 GET 请求的方法
    // @Path("all") 定义了相对于基 URI 的子路径
    // @Produces 指定该方法返回的媒体类型
    @GET
    @Path("all")
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getAllUsers() {
        return userDatabase;
    }
    // @Path("{id}") 中的 {id} 是一个路径参数
    // @PathParam("id") 用于将路径参数注入到方法中
    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUserById(@PathParam("id") int id) {
        User user = userDatabase.stream()
                .filter(u -> u.getId() == id)
                .findFirst()
                .orElse(null);
        if (user == null) {
            // 404 Not Found
            return Response.status(Response.Status.NOT_FOUND).build();
        }
        // 200 OK
        return Response.ok(user).build();
    }
    // @Consumes 指定该方法可以接受的请求体媒体类型
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createUser(User user) {
        // 简单起见,假设 ID 由客户端提供
        userDatabase.add(user);
        // 201 Created
        return Response.status(Response.Status.CREATED).entity(user).build();
    }
    @DELETE
    @Path("{id}")
    public Response deleteUser(@PathParam("id") int id) {
        boolean removed = userDatabase.removeIf(u -> u.getId() == id);
        if (removed) {
            // 204 No Content
            return Response.noContent().build();
        } else {
            // 404 Not Found
            return Response.status(Response.Status.NOT_FOUND).build();
        }
    }
}
// 一个简单的 POJO,代表用户资源
class User {
    private int id;
    private String name;
    private String email;
    // 构造器、getter 和 setter
    public User() {}
    public User(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
    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; }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

步骤 3:启动和发布服务

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

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

步骤 4:测试

  1. 运行 JerseyServer:启动 JerseyServermain 方法。
  2. 使用工具(如 Postman 或 curl)进行测试
    • 创建用户 (POST):
      curl -X POST -H "Content-Type: application/json" -d '{"id": 1, "name": "Alice", "email": "alice@example.com"}' http://localhost:8080/myapi/users
    • 获取所有用户 (GET):
      curl http://localhost:8080/myapi/users/all
    • 获取单个用户 (GET):
      curl http://localhost:8080/myapi/users/1
    • 删除用户 (DELETE):
      curl -X DELETE http://localhost:8080/myapi/users/1

技术选型对比

特性 JAX-WS (SOAP) JAX-RS (REST)
协议 SOAP (基于 XML) HTTP (通常基于 JSON)
风格 面向消息,标准化 面向资源,轻量级
数据格式 XML (强制) JSON/XML (可选,JSON 更主流)
安全性 内置 WS-Security 等标准 通常依赖 HTTPS 和 OAuth 等
性能 较低 (XML 解析开销大) 较高 (JSON 解析快,HTTP 无状态)
耦合度 高 (客户端与服务端强耦合,依赖 WSDL) 低 (客户端与服务端松耦合)
适用场景 企业内部应用、金融、电信等对安全性、事务性要求高的系统 公开 API、移动后端、微服务、Web 前后端分离项目
开发体验 相对复杂,需要处理 WSDL 简单直观,符合 HTTP 语义

更现代的选择:Spring Boot

在实际的 Java 企业级开发中,Spring Boot 已经成为开发 WebService(无论是 REST 还是 SOAP)的首选框架,它极大地简化了配置和部署。

  • 开发 RESTful API:Spring Boot 结合 Spring MVC,只需要在方法上添加 @RestController, @GetMapping, @PostMapping 等注解即可,比原生 JAX-RS 更简洁。
  • 开发 SOAP WebService:Spring Boot 提供了对 Spring-WS 的良好支持,可以轻松发布和消费 SOAP 服务。

如果你正在学习或进行项目开发,强烈建议直接学习 Spring Boot 来开发 WebService,它能让你更专注于业务逻辑,而不是繁琐的配置。

希望这份详细的指南能帮助你入门 Java WebService 开发!

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