杰瑞科技汇

Java如何发布WebService?

核心概念

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

Java如何发布WebService?-图1
(图片来源网络,侵删)
  1. WebService:一种跨编程语言、跨操作系统、跨网络的远程调用技术,它使用标准的 XML 格式进行数据交换。
  2. SOAP (Simple Object Access Protocol):WebService 的一种协议规范,基于 XML,格式严格,通常通过 HTTP 协议传输。
  3. JAX-WS:Java 官方用于创建和消费 SOAP WebService 的 API,它简化了开发过程,你只需要关注业务逻辑,底层的 XML 序列化/反序列化、SOAP 消息构建等都由它处理。
  4. Endpoint:WebService 的服务地址,客户端通过这个地址来调用服务。
  5. 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 (接口)

Java如何发布WebService?-图2
(图片来源网络,侵删)
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)中部署。

  1. WEB-INF 目录下创建 sun-jaxws.xml 文件。

    Java如何发布WebService?-图3
    (图片来源网络,侵删)

    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>
  2. 配置 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>
  3. 打包并部署:将项目打包成 .war 文件,然后部署到 Tomcat 服务器上。

    • 启动 Tomcat。
    • 访问 http://localhost:8080/your-project-name/hello?wsdl (将 your-project-name 替换成你的项目名)。
    • 如果看到 XML 内容,说明发布成功。

方式 B:动态发布 (通过 Java 代码)

这种方式更灵活,可以直接在 Java 程序中启动一个内嵌的 HTTP 服务器来发布服务,无需部署到外部容器。

  1. 创建主类 WebServicePublisher.java

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

    import 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");
        }
    }
  2. 运行主类:直接运行 WebServicePublishermain 方法。

  3. 验证:在浏览器中访问 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 注解的类并发布服务,但为了更好的控制,我们推荐使用 DefaultMethodEndpointAdapterSimpleMethodEndpointAdapter

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:运行和验证

  1. 运行主类:运行带有 @SpringBootApplication 注解的主类。
  2. 访问 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 文件(如 HelloServiceHelloService_ServiceSayHello 等)。

步骤 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!

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