Web Service 那点事儿(1)

Web Service,即“Web 服务”,简写为 WS,从字面上理解,它其实就是“基于 Web 的服务”。而服务却是双方的,有服务需求方,就有服务提供方。服务提供方对外发布服务,服务需求方调用服务提供方所发布的服务。其实也就是这些了,没有多少高大上的东西。

本文将从实战的角度,描述使用 Java 开发 WS 的工具及其使用过程。

如果说得再专业一点,WS 其实就是建立在 HTTP 协议上实现异构系统通讯的工具。没错!WS 说白了还是基于 HTTP 协议的,也就是说,数据是通过 HTTP 进行传输的。

自从有了 WS,异构系统之间的通讯不再是遥不可及的梦想。比如:可在 PHP 系统中调用 Java 系统对外发布的 WS,获取 Java 系统中的数据,或者把数据推送到 Java 系统中。

如果您想了解更多关于 WS 的那些概念与术语,可以看看下面的百度百科:

http://baike.baidu.com/view/67105.htm

今天我想与大家分享的主题是,如何在 Java 中发布与调用 WS?希望本文能够对您有所帮助!

1. 使用 JDK 发布 WS

第一步:您要做的第一件事情就是,写一个服务接口。


package demo.ws.soap_jdk;

import javax.jws.WebService;

@WebService
public interface HelloService {

    String say(String name);
}

在接口上放一个 WebService 注解,说明该接口是一个 WS 接口(称为“Endpoint,端点”),其中的方法是 WS 方法(称为“Operation,操作”)。

第二步:实现这个 WS 接口,在实现类中完成具体业务逻辑,为了简单,我们还是写一个 Hello World 意思一下吧。


package demo.ws.soap_jdk;

import javax.jws.WebService;

@WebService(
    serviceName = "HelloService",
    portName = "HelloServicePort",
    endpointInterface = "demo.ws.soap_jdk.HelloService"
)
public class HelloServiceImpl implements HelloService {

    public String say(String name) {
        return "hello " + name;
    }
}

第三步:写一个 Server 类,用于发布 WS,直接使用 JDK 提供的工具即可实现。


package demo.ws.soap_jdk;

import javax.xml.ws.Endpoint;

public class Server {

    public static void main(String[] args) {
        String address = "http://localhost:8080/ws/soap/hello";
        HelloService helloService = new HelloServiceImpl();

        Endpoint.publish(address, helloService);
        System.out.println("ws is published");
    }
}

只需使用 JDK 提供的 javax.xml.ws.Endpoint 即可发布 WS,只需提供一个 WS 的地址(address),还需提供一个服务实例(helloService)。

现在您就可以运行 Server 类的 main 方法了,会在控制台里看到“ws is published”的提示,此时恭喜您,WS 已成功发布了!

第四步:打开您的浏览器,在地址栏中输入以下地址:

http://localhost:8080/ws/soap/hello?wsdl

注意:以上地址后面有一个 ?wsdl 后缀,在 Server 类中的 address 里却没有这个后缀。此时,在浏览器中会看到如下 XML 文档:

当看到这份 WSDL 文档时,也就意味着,您发布的 WS 服务现在可以被别人使用了。

2. 通过客户端调用 WS

第一步:使用 JDK 提供的命令行工具生成 WS 客户端 jar 包。

JDK 安装目录下有个 bin 目录,里面存放了大量的命令行工具,只要您的 Path 环境变量指向了该路径,就能在命令控制台上使用 JDK 提供的相关命令。

其中,有一个名为 wsimport 的命令行工具,正是用来通过 WSDL 生成 WS 客户端代码的,您只需要输入以下命令即可:

wsimport http://localhost:8080/ws/soap/hello?wsdl
jar -cf client.jar .
rmdir /s/q demo

对以上三行命令解释如下:

  • 第一行:通过 WSDL 地址生成 class 文件
  • 第二行:通过 jar 命令将若干 class 文件压缩为一个 jar 包
  • 第三行:删除生成的 class 文件(删除根目录即可)

最终您将会得到一份名为 client.jar 的 jar 包,将这个 jar 包配置到您的 classpath 中,方便在下面的代码中使用其中的类。

技巧:可以将以上三行命令放入一个 bat 文件中,在 Windows 中双击即可运行。

第二步:写一个 Client 类,用于调用 WS,需要使用上一步生成的 WS 客户端 jar 包。


package demo.ws.soap_jdk;

public class Client {

    public static void main(String[] args) {
        HelloService_Service service = new HelloService_Service();

        HelloService helloService = service.getHelloServicePort();
        String result = helloService.say("world");
        System.out.println(result);
    }
}

以上这段代码稍微有点怪异,其中 HelloService_Service 是 jar 包中类,可以将其理解为 WS 的工厂类,通过它可以生成具体的 WS 接口,比如,调用 service.getHelloServicePort() 方法,就获取了一个 HelloService 实例,正是通过这个实例来调用其中的方法。

运行 Client 类的 main 方法,就会看到您所期望的结果“hello world”了,不妨亲自尝试一下吧。

可见,这是一个典型的“代理模式”应用场景,您实际是面向代理对象来调用 WS 的,并且这是一种“静态代理”,下面我们来谈谈,如何使用“动态代理”的方式来调用 WS?

其实 JDK 已经具备了动态代理的功能,对于 WS 而言,JDK 同样也提供了很好的工具,就像下面这段代码那样:


package demo.ws.soap_jdk;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class DynamicClient {

    public static void main(String[] args) {
        try {
            URL wsdl = new URL("http://localhost:8080/ws/soap/hello?wsdl");
            QName serviceName = new QName("http://soap_jdk.ws.demo/", "HelloService");
            QName portName = new QName("http://soap_jdk.ws.demo/", "HelloServicePort");
            Service service = Service.create(wsdl, serviceName);

            HelloService helloService = service.getPort(portName, HelloService.class);
            String result = helloService.say("world");
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

此时,只需在本地提供一个 HelloService 的接口,无需 client.jar,直接面向 WSDL 编程,只不过您需要分别定义出 serviceName 与 portName 这两个东西,最后才能调用 JDK 提供的 javax.xml.ws.Service 类生成 service 对象,它同样是一个工厂对象,通过该工厂对象获取我们需要的 HelloService 实例。貌似这种方式也不是特别动态,毕竟 HelloService 接口还是需要自行提供的。

3. 总结

通过本文,您可以了解到,不仅可以使用 JDK 发布 WS,也可以使用 JDK 调用 WS,这一切都是那么的简单而自然。但需要注意的是,这个特性是从 JDK 6 才开始提供的,如果您还在使用 JDK 5 或更低的版本,那就很遗憾了,您不得不使用以下工具来发布与调用 WS,它们分别是:

当然,发布与调用 WS 的工具不仅仅只有以上这些,而是它们是 Java 世界中最优秀的 WS 开源项目。

本文讲述的 WS 其实是一种 Java 规范,名为 JAX-WS(JSR-224),全称 Java API for XML-Based Web Services,可以将规范理解为官方定义的一系列接口。

JAX-WS 有一个官方实现,就是上面提到的 JAX-WS RI,它是 Oracle 公司提供的实现,而 Apache 旗下的 Axis 与 CXF 也同样实现了该规范。Axis 相对而言更加老牌一些,而 CXF 的前世就是 XFire,它是一款著名的 WS 框架,擅长与 Spring 集成。

从本质上讲,JAX-WS 是基于 SOAP 的,而 SOAP 的全称是 Simple Object Access Protocol(简单对象访问协议),虽然名称里带有“简单”二字,其实并不简单,不相信您可以百度一下。

为了让 WS 的开发与使用变得更加简单、更加轻量级,于是出现了另一种风格的 WS,名为 JAX-RS(JSR-339),全称 Java API for RESTful Web Services,同样也是一种规范,同样也有若干实现,它们分别是:

其中,Jersey 是 Oracle 官方提供的实现,Restlet 是最老牌的实现,RESTEasy 是 JBoss 公司提供的实现,CXF 是 Apache 提供的实现(上文已做介绍)。

可见,CXF 不仅用于开发基于 SOAP 的 WS,同样也适用于开发基于 REST 的 WS,这么好的框架我们怎能错过?

如何使用 CXF 简化我们的 WS 开发?我们下期再见!

时间: 2024-10-13 07:24:17

Web Service 那点事儿(1)的相关文章

Web Service 那点事儿(4)—— 使用 CXF 开发 REST 服务

现在您已经学会了如何使用 CXF 开发基于 SOAP 的 Web 服务,也领略了 Spring + CXF 这个强大的组合,如果您错过了这精彩的一幕,请回头看看这篇吧: Web Service 那点事儿(2) —— 使用 CXF 开发 SOAP 服务 今天我们将视角集中在 REST 上,它是继 SOAP 以后,另一种广泛使用的 Web 服务.与 SOAP 不同,REST 并没有 WSDL 的概念,也没有叫做“信封”的东西,因为 REST 主张用一种简单粗暴的方式来表达数据,传递的数据格式可以是

Web Service 那点事儿(2)—— 使用 CXF 开发 SOAP 服务

选框架犹如选媳妇,选来选去,最后我还是选了“丑媳妇(CXF)”,为什么是它?因为 CXF 是 Apache 旗下的一款非常优秀的 WS 开源框架,具备轻量级的特性,而且能无缝整合到 Spring 中. 其实 CXF 是两个开源框架的整合,它们分别是:Celtix 与 XFire,前者是一款 ESB 框架,后者是一款 WS 框架.话说早在 2007 年 5 月,当 XFire 发展到了它的鼎盛时期(最终版本是 1.2.6),突然对业界宣布了一个令人震惊的消息:“XFire is now CXF”,

在GlassFish应用服务器上创建并运行你的第一个Restful Web Service【翻译】

前言 本人一直开发Android应用,目前Android就业形势恶劣,甚至会一路下滑,因此决定学习服务器开发.采用的语言是java,IDE是Intellij,在下载Intellij的同时看到官网很多优秀的guide文章,于是按照guide成功完成了一个RESTful的demo.官方文档非常简洁,给我带来了很大的帮助,于是翻译之,希望对其他不愿意看原文的人有所帮助.由于水平有限,读者发现错误请指正,谢谢. 原文地址: https://www.jetbrains.com/help/idea/2016

Axis实现 web service接口开发 + 客户端调用

看到网上挺多人找webservice axis开发案例,但是网上较多的都是有点乱,初学者不太容易看得懂,所以最近看到自己终于有了点空闲时间,就上传了一份比较简单的webservice axis的完整案例. 只适用于初学者. 一.新建一个web项目 导入lib包. 2.配置 web.xml <!-- axis 配置 -->   <servlet>         <display-name>Apache-Axis Servlet</display-name>

Axis2实现 web service接口开发 + 客户端调用

一. 新建一个web项目, 1.打开axis2.war包,将conf,lib,modules三个文件夹复制到项目的WEB-INF文件夹下,再在WEB-INF目录下新建一个services文件夹,然后在services文件下新建一个文件夹(任意取名): 再新建META-INF文件夹,最后再新增services.xml,接口信息就写在这里面. 具体路径:WEB-INF/services/myservice/META-INF/services.xml 2.配置 web.xml .加载axis2 和 a

VB.NET,C#.NET调用Web Service,利用visual studio 的实现方法

在VB.NET调用Web Service提供的服务 技术qq交流群:JavaDream:251572072 下面是一篇文章比较详细,其实具体操作很简单,把Web Service服务地址,利用工具(VS2010),通过添加引用的形式,添加到项目中来就可以应用了. 大家如果这个地方不会操场的话,可以问问我QQ:1606841559 当Web Service已经处于对外提供服务状态,VB.NET就可以通过HTTP"调用"来使用这些服务了.当然前提是要了解Web Service对外提供服务所对

asp.net ajax客户端框架如何调用Web Service

1:Web Service类添加 [System.Web.Script.Services.ScriptService]特性2:需要异步调用的方法需要添加[WebMethod]特性 3,页面必须添加ScriptManager控件(有且唯一)4: ScriptManager添加对相应的Web Service的ServiceReference5:在客户端使用如下格式调用: [NameSpace].[ClassName].[MethodName](parm1,parm2,...,callbackFunc

zzWCF实现RESTFul Web Service

http://www.cnblogs.com/KeithWang/archive/2012/02/14/2351826.html http://blog.csdn.net/qq_26054303/article/details/48655985 http://www.cnblogs.com/LNCLSH/p/3781572.html 共同学习了前面一些概念,终于开始正题了哈.RESTful的Web Service调用直观,返回的内容容易解析.这里先会描述一个简单的场景--Web Service提

Web Service和WCF的到底有什么区别

[1]Web Service:严格来说是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XML扩展标记语言来表示数据(这个是夸语言和平台的关键).微软的Web服务实现称为ASP.NET Web Service.它使用Soap简单对象访问协议来实现分布式环境里应用程序之间的数据交互.WSDL来实现服务接口相关的描述.此外Web services 可以注册到UDDI中心.供其客户查找使用.