核心概念
在开始之前,先理解几个基本概念:

- WebService:一种跨编程语言、跨操作系统、跨网络的远程调用技术,它使用标准的 XML 格式进行数据交换。
- SOAP (Simple Object Access Protocol):WebService 的一种协议规范,基于 XML,格式严格,通常通过 HTTP 协议传输。
- JAX-WS:Java 官方用于创建和消费 SOAP WebService 的 API,它简化了开发过程,你只需要关注业务逻辑,底层的 XML 序列化/反序列化、SOAP 消息构建等都由它处理。
- Endpoint:WebService 的服务地址,客户端通过这个地址来调用服务。
- WSDL (Web Services Description Language):一个 XML 文件,用来描述 WebService 的功能、地址、接口、参数等信息,客户端通过 WSDL 文件来了解如何调用你的服务。
使用 JAX-WS (标准 JavaEE 方式)
这是最传统、最标准的 Java WebService 发布方式,适用于 JavaEE 容器(如 Tomcat, JBoss, WebLogic)。
步骤 1:创建一个 Java Web 项目
在你的 IDE(如 IntelliJ IDEA 或 Eclipse)中创建一个标准的 Maven Web 项目。
步骤 2:编写服务接口和实现类
服务接口定义了客户端可以调用的方法。
com.example.webservice.HelloService.java (接口)

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
// @WebService 注解将这个类标记为一个 WebService 接口
@WebService
public interface HelloService {
// @WebMethod 注解标记一个方法为 WebService 的可调用方法
// @WebParam 注解用于指定方法的参数名
@WebMethod
String sayHello(@WebParam(name = "name") String name);
}
com.example.webservice.HelloServiceImpl.java (实现类)
import javax.jws.WebService;
// @WebService 注解将这个类标记为 WebService 的实现
// endpointInterface 属性指定了它实现的接口
@WebService(endpointInterface = "com.example.webservice.HelloService")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "Hello, " + name + "! Welcome to JAX-WS WebService.";
}
}
步骤 3:发布 WebService
发布 WebService 的方式有两种:静态发布和动态发布。
方式 A:静态发布 (通过 sun-jaxws.xml 配置)
这种方式需要配置描述符文件,适合在 JavaEE 容器(如 Tomcat)中部署。
-
在
WEB-INF目录下创建sun-jaxws.xml文件。
(图片来源网络,侵删)src/main/webapp/WEB-INF/sun-jaxws.xml<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <endpoint name="HelloService" implementation="com.example.webservice.HelloServiceImpl" url-pattern="/hello"/> </endpoints> -
配置
web.xml:在web.xml中添加Endpoint监听器。src/main/webapp/WEB-INF/web.xml<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app> -
打包并部署:将项目打包成
.war文件,然后部署到 Tomcat 服务器上。- 启动 Tomcat。
- 访问
http://localhost:8080/your-project-name/hello?wsdl(将your-project-name替换成你的项目名)。 - 如果看到 XML 内容,说明发布成功。
方式 B:动态发布 (通过 Java 代码)
这种方式更灵活,可以直接在 Java 程序中启动一个内嵌的 HTTP 服务器来发布服务,无需部署到外部容器。
-
创建主类
WebServicePublisher.javasrc/main/java/com/example/webservice/WebServicePublisher.javaimport com.example.webservice.HelloServiceImpl; import javax.xml.ws.Endpoint; public class WebServicePublisher { public static void main(String[] args) { // 创建服务实现类的实例 Object implementor = new HelloServiceImpl(); // 定义 WebService 的发布地址 String address = "http://localhost:8888/hello"; // 发布服务 Endpoint.publish(address, implementor); System.out.println("WebService 发布成功!"); System.out.println("WSDL 地址: " + address + "?wsdl"); } } -
运行主类:直接运行
WebServicePublisher的main方法。 -
验证:在浏览器中访问
http://localhost:8888/hello?wsdl,查看 WSDL 文件。
使用 Spring Boot (现代、简化方式)
Spring Boot 极大地简化了 Web 服务的开发,是当前的主流选择。
步骤 1:创建 Spring Boot 项目
使用 Spring Initializr 创建一个新项目,添加以下依赖:
Spring Web: 用于创建 Web 应用。Spring Web Services: 用于支持 SOAP WebService。WSDL4J: 用于处理 WSDL 文件。
步骤 2:编写服务接口和实现类
这里的实现与 JAX-WS 方式基本相同。
com.example.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);
}
com.example.webservice.HelloServiceImpl.java
import com.example.webservice.HelloService;
import org.springframework.stereotype.Service;
import javax.jws.WebService;
@WebService(serviceName = "HelloService", // 指定服务名
portName = "HelloServicePort", // 指定端口名
targetNamespace = "http://webservice.example.com/", // 指定命名空间
endpointInterface = "com.example.webservice.HelloService") // 指定接口
@Service
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "Hello, " + name + "! Welcome to Spring Boot WebService.";
}
}
注意:Spring Boot 中,实现类通常用 @Service 或 @Component 注解。
步骤 3:配置和发布服务
Spring Boot 会自动扫描带有 @WebService 注解的类并发布服务,但为了更好的控制,我们推荐使用 DefaultMethodEndpointAdapter 和 SimpleMethodEndpointAdapter。
src/main/java/com/example/webservice/WebServiceConfig.java
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.ws.wsdl.wsdl11.Wsdl11Definition;
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
// 注册 MessageDispatcherServlet
@Bean
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(servlet, "/ws/*");
}
// 创建 WSDL 定义
@Bean(name = "hello")
public Wsdl11Definition defaultWsdl11Definition(HelloService helloService) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("HelloServicePort");
wsdl11Definition.setLocationUri("/ws/hello"); // 发布地址
wsdl11Definition.setTargetNamespace("http://webservice.example.com/");
wsdl11Definition.setSchema(new ClassPathResource("schemas/hello.xsd")); // 可选,定义 XSD
return wsdl11Definition;
}
}
上面的配置是标准的 Spring WS 配置,对于简单的 JAX-WS 服务,Spring Boot 的自动配置通常已经足够。
步骤 4:运行和验证
- 运行主类:运行带有
@SpringBootApplication注解的主类。 - 访问 WSDL:Spring Boot 默认会在一个固定的路径下生成 WSDL,根据你的配置,访问地址通常是:
http://localhost:8080/ws/hello.wsdl- 或者
http://localhost:8088/ws/hello?wsdl(如果你在application.properties中配置了server.port=8088)
如何调用(消费)WebService
这里提供一个简单的 Java 客户端调用示例。
步骤 1:使用 JDK 自带的 wsimport 工具生成客户端代码
打开命令行,进入你的项目目录,执行以下命令:
# -p: 指定生成的包名 # -d: 指定代码输出目录 # -keep: 保留生成的源文件 wsimport -p com.example.webservice.client -d src/main/java -keep http://localhost:8888/hello?wsdl
执行后,会在 com.example.webservice.client 包下生成一堆 Java 文件(如 HelloService、HelloService_Service、SayHello 等)。
步骤 2:编写客户端代码
src/main/java/com/example/webservice/ClientTest.java
import com.example.webservice.client.HelloService;
import com.example.webservice.client.HelloService_Service;
public class ClientTest {
public static void main(String[] args) {
// 创建服务视图 (Service)
HelloService_Service service = new HelloService_Service();
// 从服务视图中获取端口 (Port)
HelloService helloPort = service.getHelloServicePort();
// 调用远程方法
String response = helloPort.sayHello("WebService User");
System.out.println("收到服务端响应: " + response);
}
}
运行 ClientTest,如果一切正常,你会在控制台看到输出:
收到服务端响应: Hello, WebService User! Welcome to JAX-WS WebService.
总结与对比
| 特性 | JAX-WS (传统方式) | Spring Boot (现代方式) |
|---|---|---|
| 依赖 | JavaEE 容器 (如 Tomcat) 或内嵌服务器 | Spring Boot 内嵌服务器 (Tomcat, Jetty) |
| 配置 | 需要 web.xml, sun-jaxws.xml 等XML配置 |
主要通过 @Configuration 和 Java Bean 配置,或自动配置 |
| 开发效率 | 相对繁琐,需要处理部署和XML配置 | 极高,"约定优于配置",快速启动和开发 |
| 集成度 | 与 Spring/Spring Boot 集成需要额外配置 | 与 Spring 生态无缝集成,易于整合事务、安全等 |
| 适用场景 | 维护旧项目、在现有JavaEE应用中添加服务 | 新项目、微服务、需要快速迭代和现代化开发的场景 |
推荐选择:
- 新项目首选 Spring Boot:它更简单、更高效、更符合现代开发潮流。
- 旧项目或特定环境:如果必须在 JavaEE 容器中部署,或者环境不允许使用 Spring Boot,JAX-WS 是可靠的选择。
希望这份详细的指南能帮助你成功发布你的第一个 Java WebService!
