杰瑞科技汇

Java webservice教程,如何快速上手开发?

目录

  1. 什么是 WebService?
  2. 为什么使用 WebService?
  3. WebService 的两种主流实现方式
    • 1. SOAP (JAX-WS)
    • 2. REST (Spring Web)
  4. 实战教程:使用 JAX-WS 创建 SOAP WebService
    • 1. 环境准备
    • 2. 创建服务端
    • 3. 创建客户端
    • 4. 运行和测试
  5. 实战教程:使用 Spring Boot 创建 RESTful WebService
    • 1. 环境准备
    • 2. 创建项目
    • 3. 编写 Controller
    • 4. 启动和测试
  6. JAX-WS vs REST (Spring Web) 如何选择?
  7. 总结与进阶

什么是 WebService?

WebService 是一种跨编程语言和跨操作系统平台的远程调用技术,它允许你通过 网络 使用 HTTP 协议 调用另一个系统的服务,就像调用本地方法一样。

Java webservice教程,如何快速上手开发?-图1
(图片来源网络,侵删)

WebService 就是一个“网络上的服务”,它暴露了一个或多个可以远程调用的方法。

为什么使用 WebService?

  • 系统解耦:不同系统(如 Java 和 .NET)可以通过 WebService 进行通信,而不需要关心对方内部的技术实现。
  • 跨平台/跨语言:WebService 基于 XML (SOAP) 或 JSON (REST) 作为数据交换格式,任何支持这些格式的语言都可以成为客户端或服务端。
  • 可复用性:可以将通用的业务逻辑封装成 WebService,供多个应用调用,避免重复开发。

WebService 的两种主流实现方式

WebService 主要有两种风格:SOAP 和 REST,它们在理念、格式和使用场景上都有很大不同。

1. SOAP (JAX-WS)

  • 概念:SOAP (Simple Object Access Protocol) 是一个协议,它定义了一套非常严格的、基于 XML 的消息格式,它有自己的规范,不仅仅是 RPC(远程过程调用)。
  • 特点
    • 格式严格:消息必须是格式良好的 XML。
    • 重量级:由于 XML 标签多,消息体积较大,解析速度相对较慢。
    • 标准化:拥有完善的标准(如 WS-Security, WS-Addressing 等),支持事务、安全等企业级特性。
    • 平台无关:通过 WSDL (Web Services Description Language) 文件描述服务接口,客户端可以根据 WSDL 生成调用代码。
  • Java 实现:JAX-WS (Java API for XML Web Services) 是 Java 官方提供的一套用于开发 SOAP WebService 的 API,它简化了开发过程,你只需要用注解来标注你的 Java 类和方法,JAX-WS 运行时会帮你处理底层的 XML 转换和网络通信。
  • 适用场景:企业级应用、银行、金融、电信等对安全性、事务性要求高的场景。

2. REST (Spring Web)

  • 概念:REST (Representational State Transfer) 不是一种标准,而是一种软件架构风格,它更轻量级,更符合 Web 的原生理念。
  • 特点
    • 格式灵活:通常使用 JSON 作为数据交换格式,XML 也可以,JSON 更轻便,解析更快。
    • 轻量级:没有复杂的 XML 包裹,数据直接,网络开销小。
    • 无状态:服务器不保存客户端的状态,每次请求都包含所有必要信息。
    • 资源导向:将一切视为资源,通过 URL 来定位资源,使用 HTTP 动词(GET, POST, PUT, DELETE)来操作资源。
  • Java 实现:在 Java 生态中,Spring Web (Spring MVC / Spring Boot) 是实现 RESTful 风格 WebService 的绝对主流,它通过 @RestController@GetMapping@PostMapping 等注解,让你能非常方便地创建 REST API。
  • 适用场景:Web 应用的前后端分离、移动 App 后端、微服务之间的通信等绝大多数现代 Web 开发场景。

实战教程:使用 JAX-WS 创建 SOAP WebService

我们将创建一个简单的计算器服务,提供 addsubtract 方法。

1. 环境准备

  • JDK 8 或更高版本
  • Maven (用于项目管理)
  • IDE (如 IntelliJ IDEA 或 Eclipse)

2. 创建服务端

步骤 1:创建 Maven 项目

Java webservice教程,如何快速上手开发?-图2
(图片来源网络,侵删)

创建一个普通的 Maven Java 项目。

步骤 2:添加依赖

pom.xml 中添加 JAX-WS 运行时依赖,我们使用 com.sun.xml.ws:jaxws-rt,这是 JAX-WS 的参考实现。

<dependencies>
    <!-- JAX-WS Runtime -->
    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>4.0.1</version>
    </dependency>
</dependencies>

步骤 3:创建服务接口和实现

Java webservice教程,如何快速上手开发?-图3
(图片来源网络,侵删)

定义一个服务接口,并用 JAX-WS 的注解来标记它。

src/main/java/com/example/webservice/Calculator.java

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// @WebService: 将这个类标记为一个 WebService
@WebService
// @SOAPBinding: 定义 SOAP 消息的风格,默认是 DOCUMENT,这里明确为 RPC 风格
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface Calculator {
    // @WebMethod: 将这个公共方法暴露为 WebService 的一个操作
    @WebMethod
    int add(int a, int b);
    @WebMethod
    int subtract(int a, int b);
}

创建这个接口的实现类。

src/main/java/com/example/webservice/CalculatorImpl.java

import javax.jws.WebService;
// 注意:实现类不需要添加 @WebService 注解
@WebService(endpointInterface = "com.example.webservice.Calculator")
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int a, int b) {
        System.out.println("WebService is adding " + a + " and " + b);
        return a + b;
    }
    @Override
    public int subtract(int a, int b) {
        System.out.println("WebService is subtracting " + b + " from " + a);
        return a - b;
    }
}

步骤 4:发布 WebService

创建一个主类来启动和发布我们的服务。

src/main/java/com/example/webservice/CalculatorPublisher.java

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

步骤 5:运行服务端

运行 CalculatorPublishermain 方法,如果一切顺利,你会在控制台看到: Calculator WebService is published at: http://localhost:8888/calculator

你的 SOAP WebService 已经成功启动了!你可以访问 http://localhost:8888/calculator?wsdl 来查看服务的 WSDL 描述文件。

3. 创建客户端

创建一个新的 Maven 项目(或同一个项目的另一个模块)。

步骤 1:添加依赖

与服务端相同的依赖。

步骤 2:使用 WSDL 生成客户端代码

最简单的方式是使用 JDK 自带的 wsimport 工具,打开命令行,进入客户端项目的 src/main/java 目录,执行以下命令:

wsimport -keep -p com.example.webservice.client http://localhost:8888/calculator?wsdl
  • -keep: 生成源代码。
  • -p com.example.webservice.client: 指定生成代码的包名。
  • http://...: WSDL 文件的地址。

执行后,会生成一堆 Java 文件(.class.java),这些就是客户端代理代码。

步骤 3:编写客户端调用代码

src/main/java/com/example/webservice/client/CalculatorClient.java

public class CalculatorClient {
    public static void main(String[] args) {
        // 通过生成的 Service 类来获取 Port(即服务的代理对象)
        CalculatorService service = new CalculatorService();
        Calculator calculatorProxy = service.getCalculatorPort();
        // 像调用本地方法一样调用远程服务
        int sum = calculatorProxy.add(10, 25);
        System.out.println("10 + 25 = " + sum);
        int difference = calculatorProxy.subtract(100, 50);
        System.out.println("100 - 50 = " + difference);
    }
}

步骤 4:运行客户端

运行 CalculatorClientmain 方法,你会看到输出:

10 + 25 = 35
100 - 50 = 50

服务端控制台也会打印出相应的日志。


实战教程:使用 Spring Boot 创建 RESTful WebService

这是目前更流行、更简单的方式。

1. 环境准备

  • JDK 8 或更高版本
  • MavenGradle
  • IDE

2. 创建项目

最简单的方式是使用 Spring Initializr (https://start.spring.io)。

  1. Project: Maven Project
  2. Language: Java
  3. Spring Boot: 选择一个稳定版本 (如 3.x.x)
  4. Project Metadata:
    • Group: com.example
    • Artifact: rest-webservice
    • Name: rest-webservice
    • Packaging: Jar
    • Java: 17 (或你的版本)
  5. Dependencies: 添加 Spring Web 依赖。

点击 "GENERATE" 下载项目,并用你的 IDE 打开。

3. 编写 Controller**

创建一个 Controller 类来处理 HTTP 请求。

src/main/java/com/example/restwebservice/StudentController.java

import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
// @RestController: 组合了 @Controller 和 @ResponseBody,表示这个类中的所有方法返回的数据都直接写入 HTTP 响应体中
@RestController
// @RequestMapping: 为这个控制器下的所有请求提供一个基础路径
@RequestMapping("/api/students")
public class StudentController {
    // 模拟一个数据源
    private List<Student> studentList = new ArrayList<>(List.of(
            new Student(1, "张三"),
            new Student(2, "李四")
    ));
    // @GetMapping: 处理 HTTP GET 请求
    @GetMapping
    public List<Student> getAllStudents() {
        System.out.println("Getting all students...");
        return studentList;
    }
    // @GetMapping("/{id}": 处理带路径变量的 GET 请求,/api/students/1
    @GetMapping("/{id}")
    public Student getStudentById(@PathVariable int id) {
        System.out.println("Getting student with id: " + id);
        // 使用 Java 8 的 Stream API 查找学生
        return studentList.stream()
                .filter(s -> s.getId() == id)
                .findFirst()
                .orElseThrow(() -> new RuntimeException("Student not found with id: " + id));
    }
    // @PostMapping: 处理 HTTP POST 请求,用于创建新资源
    @PostMapping
    public Student createStudent(@RequestBody Student student) {
        System.out.println("Creating student: " + student.getName());
        // 在实际应用中,这里应该生成新的 ID 并保存到数据库
        student.setId(studentList.size() + 1);
        studentList.add(student);
        return student;
    }
    // @PutMapping: 处理 HTTP PUT 请求,用于更新资源
    @PutMapping("/{id}")
    public Student updateStudent(@PathVariable int id, @RequestBody Student studentDetails) {
        System.out.println("Updating student with id: " + id);
        Student student = studentList.stream()
                .filter(s -> s.getId() == id)
                .findFirst()
                .orElseThrow(() -> new RuntimeException("Student not found with id: " + id));
        student.setName(studentDetails.getName());
        return student;
    }
    // @DeleteMapping: 处理 HTTP DELETE 请求,用于删除资源
    @DeleteMapping("/{id}")
    public String deleteStudent(@PathVariable int id) {
        System.out.println("Deleting student with id: " + id);
        boolean removed = studentList.removeIf(s -> s.getId() == id);
        if (!removed) {
            throw new RuntimeException("Student not found with id: " + id);
        }
        return "Student with id " + id + " has been deleted.";
    }
}
// 一个简单的 POJO (Plain Old Java Object)
class Student {
    private int id;
    private String name;
    public Student() {}
    public Student(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; }
}

4. 启动和测试

步骤 1:启动应用

找到主启动类(RestWebserviceApplication.java),右键运行 main 方法,Spring Boot 会启动一个内嵌的 Tomcat 服务器,默认监听 8080 端口。

步骤 2:使用 API 工具测试

强烈推荐使用 Postmancurl 来测试你的 API。

  • 获取所有学生

    • Method: GET
    • URL: http://localhost:8080/api/students
    • Response (JSON):
      [
        {"id":1,"name":"张三"},
        {"id":2,"name":"李四"}
      ]
  • 根据 ID 获取学生

    • Method: GET
    • URL: http://localhost:8080/api/students/1
    • Response (JSON):
      {"id":1,"name":"张三"}
  • 创建新学生

    • Method: POST
    • URL: http://localhost:8080/api/students
    • Body (raw, JSON):
      {"name":"王五"}
    • Response (JSON):
      {"id":3,"name":"王五"}
  • 更新学生

    • Method: PUT
    • URL: http://localhost:8080/api/students/1
    • Body (raw, JSON):
      {"name":"张三丰"}
    • Response (JSON):
      {"id":1,"name":"张三丰"}
  • 删除学生

    • Method: DELETE
    • URL: http://localhost:8080/api/students/2
    • Response: Student with id 2 has been deleted.

JAX-WS vs REST (Spring Web) 如何选择?

特性 JAX-WS (SOAP) REST (Spring Web)
本质 协议 架构风格
数据格式 XML (严格) JSON (主流), XML (可选)
重量级 重 (XML标签多) 轻 (JSON简洁)
标准化 高 (WSDL, WS-*) 低 (遵循HTTP标准,无统一规范)
状态 无状态 无状态
安全性 内置复杂的安全标准 通常通过 HTTPS 和 OAuth2 等实现
工具支持 成熟,有WSDL自动生成客户端代码 依赖HTTP客户端库,手动构建请求
适用场景 企业级应用、金融、电信、需要强事务和WS-*标准的场景 Web应用、移动后端、微服务、前后端分离项目
学习曲线 相对陡峭 相对平缓,更符合Web开发者直觉

一句话总结

  • 如果你的项目需要遵循严格的行业标准、处理复杂的事务和安全,并且可能需要与老式的 .NET 系统集成,选择 JAX-WS
  • 如果你正在开发现代 Web 应用,追求开发效率、轻量级通信,并且你的客户端是浏览器或移动 App,毫无疑问选择 REST (Spring Web)

总结与进阶

  • 本教程带你从零开始,分别用 Java 的原生 JAX-WS 技术和现代的 Spring Boot 框架实现了 WebService,理解 SOAP 和 REST 的区别以及它们各自的适用场景是成为一名合格 Java 后端开发者的关键技能。

  • 进阶学习

    • JAX-WS 进阶:学习 @HandlerChain 处理 SOAP 消息头、WS-Security 安全配置、异步调用等。
    • REST 进阶
      • API 文档:学习使用 Swagger (OpenAPI) 自动生成和测试 API 文档。
      • 数据验证:使用 Hibernate Validator 对请求数据进行校验。
      • 全局异常处理:使用 @ControllerAdvice 统一处理异常。
      • API 版本控制:学习如何管理 API 的不同版本。
      • 性能优化:了解 JSON 序列化库(如 Jackson)的配置和性能调优。

希望这份详细的教程能帮助你顺利掌握 Java WebService 开发!

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