目录
第1章 成为程序员 1.1 选择编程语言 1.2 告诉计算机做什么 1.3 程序的工作原理 1.4 为什么程序不能正常工作 1.5 选择 Java编程工具 1.6 安装 Java开发工具 1.7 总结 1.8 问与答 1.9 测验 1.9.1 问题 1.9.2 答案 1.10 练习 第2章 编写第一个程序 2.1 编写程序所需的工具 2.2 创建 Saluton 程序 2.3 开始输入程序 2.3.1 class语句 2.3.2 main语句的作用 2.3.3 大括号 2.4 在变量中存储信息 2.5 保存编写好的程序 2.6 将程序编译为 class文件 2.7 修复错误 2.8 运行 Java程序 2.9 总结 2.10 问与答 2.11 测验 2.11.1 问题 2.11.2 答案 2.12 练习 第3章 Java之旅 3.1 第一站:Oracle 3.2 去 Java学校 3.3 在 JavaWorld 用午餐 3.4 在 NASA仰望天穹 3.5 回归正题 3.6 到 Java Boutique 去问路 3.7 在手机上运行 Java 3.8 总结 3.9 问与答 3.10 测验 3.10.1 问题 3.10.2 答案 3.11 练习 第4章 理解Java程序的工作原理 4.1 创建应用程序 4.2 向应用程序传递参数 4.3 创建 applet 4.4 总结 4.5 问与答 4.6 测验 4.6.1 问题 4.6.2 答案 4.7 练习 第5章 在程序中存储和修改信息 5.1 语句和表达式 5.2 指定变量类型 5.2.1 整数和浮点数 5.2.2 字符和字符串 5.2.3 其他数值类型的变量 5.2.4 布尔型变量 5.3 给变量命名 5.4 在变量中存储信息 5.5 运算符 5.5.1 变量的递增与递减 5.5.2 运算符优先级 5.6 使用表达式 5.7 总结 5.8 问与答 5.9 测验 5.9.1 问题 5.9.2 答案 5.10 练习 第6章 使用字符串来交流 6.1 在字符串中存储文本 6.2 在程序中显示字符串 6.3 在字符串中使用特殊字符 6.4 拼接字符串 6.5 将其他变量用于字符串中 6.6 字符串的高级处理 6.6.1 比较两个字符串 6.6.2 确定字符串的长度 6.6.3 改变字符串的大小写 6.6.4 查找字符串 6.7 导演及演员名单 6.8 总结 6.9 问与答 6.10 测验 6.10.1 问题 6.10.2 答案 6.11 练习 第7章 使用条件测试进行判断 7.1 if语句 7.1.1 小于和大于的比较 7.1.2 相等和不等 7.1.3 使用块语句组织程序 7.2 if-else 语句 7.3 switch语句 7.4 条件运算符 7.5 观察时钟 7.6 总结 7.7 问与答 7.8 测验 7.8.1 问题 7.8.2 答案 7.9 练习 第8章 使用循环重复执行操作 8.1 for循环 8.2 while 循环 8.3 do-while 循环 8.4 退出循环 8.5 给循环命名 8.6 测试计算机的运行速度 8.7 总结 8.8 问与答 8.9 测验 8.9.1 问题 8.9.2 答案 8.10 练习 第9章 使用数组存储信息 9.1 创建数组 9.2 使用数组 9.3 多维数组 9.4 对数组进行排序 9.5 对字符串中的字符计数 9.6 总结 9.7 问与答 9.8 测验 9.8.1 问题 9.8.2 答案 9.9 练习 第10章 创建第一个对象 10.1 面向对象编程的工作原理 10.2 对象示例 10.3 什么是对象 10.4 理解继承 10.5 建立继承层次 10.6 转换对象和简单变量 10.6.1 简单变量的类型转换 10.6.2 对象类型转换 10.6.3 在简单变量和对象之间进行转换 10.6.4 自动封装和拆封 10.7 创建对象 10.8 总结 10.9 问与答 10.10 测验 10.10.1 问题 10.10.2 答案 10.11 练习 第11章 描述对象 11.1 创建变量 11.2 创建类变量 11.3 用方法来创建行为 11.3.1 声明方法 11.3.2 参数不同的类似方法 11.3.3 构造函数 11.3.4 类方法 11.3.5 方法中变量的作用域 11.4 将一个类放在另一个类中 11.5 使用关键字this 11.6 使用类方法和类变量 11.7 总结 11.8 问与答 11.9 测验 11.9.1 问题 11.9.2 答案 11.10 练习 第12章 充分利用现有对象 12.1 继承的威力 12.1.1 继承行为和属性 12.1.2 覆盖方法 12.2 建立继承 12.3 使用现有的对象 12.4 将相同类型的对象存储到 Vector 中 12.5 创建子类 12.6 总结 12.7 问与答 12.8 测验 12.8.1 问题 12.8.2 答案 12.9 练习 第13章 创建简单的用户界面 13.1 Swing 和抽象窗口工具包 13.2 使用组件 13.2.1 窗口和框架 13.2.2 按钮 13.2.3 标签和文本框 13.2.4 复选框 13.2.5 组合框 13.2.6 文本区域 13.2.7 面板 13.3 创建自己的组件 13.4 总结 13.5 问与答 13.6 测验 13.6.1 问题 13.6.2 答案 13.7 练习 第14章 用户界面的布局 14.1 使用布局管理器 14.1.1 GridLayout管理器 14.1.2 BorderLayout管理器 14.1.3 BoxLayout管理器 14.1.4 使用Insets将组件隔开 14.2 应用程序的界面布局 14.3 总结 14.4 问与答 14.5 测验 14.5.1 问题 14.5.2 答案 14.6 练习 第15章 响应用户输入 15.1 让程序监听 15.2 设置要监听的组件 15.3 处理用户事件 15.3.1 复选框和组合框事件 15.3.2 键盘事件 15.3.3 启用和禁用组件 15.4 完善图形应用程序 15.5 总结 15.6 问与答 15.7 测验 15.7.1 问题 15.7.2 答案 15.8 练习 第16章 创建复杂的用户界面 16.1 滚动窗格 16.2 滑块 16.3 变更监听器 16.4 使用图像图标和工具栏 16.5 总结 16.6 问与答 16.7 测验 16.7.1 问题 16.7.2 答案 16.8 练习 第17章 创建交互式Web程序 17.1 标准applet方法 17.1.1 在applet窗口中绘画 17.1.2 初始化applet 17.1.3 启动和停止applet 17.1.4 销毁applet 17.2 将applet放到Web页面中 17.3 创建applet 17.3.1 在applet窗口中绘画 17.3.2 测试SalutonApplet程序 17.4 从Web页面传递参数 17.5 在applet中接收参数 17.6 在applet中处理参数 17.7 使用object标记 17.8 总结 17.9 问与答 17.10 测验 17.10.1 问题 17.10.2 答案 17.11 练习 第18章 处理程序中的错误 18.1 异常 18.1.1 在try-catch块中捕获异常 18.1.2 捕获多种不同的异常 18.1.3 出现异常后进行处理 18.1.4 抛出异常 18.1.5 忽略异常 18.2 抛出和捕获异常 18.3 总结 18.4 问与答 18.5 测验 18.5.1 问题 18.5.2 答案 18.6 练习 第19章 创建线程程序 19.1 线程 19.1.1 降低程序的速度 19.1.2 创建线程 19.2 使用线程 19.2.1 声明类 19.2.2 创建变量 19.3 从init( )开始 19.4 在创建URL时捕获错误 19.5 在paint( )方法中处理屏幕更新 19.6 启动线程 19.6.1 运行线程 19.6.2 停止线程 19.7 处理鼠标单击 19.8 循环显示链接 19.9 总结 19.10 问与答 19.11 测验 19.11.1 问题 19.11.2 答案 19.12 练习 第20章 读写文件 20.1 流 20.1.1 文件 20.1.2 从流中读取数据 20.1.3 缓冲输入流 20.2 将数据写入流中 20.3 读写配置属性 20.4 总结 20.5 问与答 20.6 测验 20.6.1 问题 20.6.2 答案 20.7 练习 第21章 读写XML数据 21.1 创建XML文件 21.2 读取XML文件 21.3 读取 RSS 聚合内容(Syndication Feeds) 21.4 总结 21.5 问与答 21.6 测验 21.6.1 问题 21.6.2 答案 21.7 练习 第22章 利用JAX-WS开发Web服务 22.1 定义服务端点接口 使用注解来简化Java代码 22.2 创建服务实现Bean 22.3 发布Web服务 22.4 使用Web服务描述语言文件 22.5 创建Web服务客户端 22.6 总结 22.7 问与答 22.8 测验 22.8.1 问题 22.8.2 答案 22.9 练习 第23章 创建Java2D图形 23.1 使用Font类 23.2 使用Color类 23.3 创建自定义颜色 23.4 绘制直线和形状 23.4.1 绘制直线 23.4.2 绘制矩形 23.4.3 绘制椭圆和圆 23.4.4 绘制弧线 23.5 绘制饼图 23.6 总结 23.7 问与答 23.8 测验 23.8.1 问题 23.8.2 答案 23.9 练习 第24章 编写Android app 24.1 Android简介 24.2 创建 Android app 24.2.1 剖析一个Android新项目 24.2.2 创建app 24.2.3 安装Android模拟器 24.2.4 创建调试配置 24.3 运行app 24.4 设计真实的app 24.4.1 组织资源 24.4.2 配置app的Manifest文件 24.4.3 设计用户界面 24.4.4 编写Java代码 24.5 总结 24.6 问与答 24.7 测验 24.7.1 问题 24.7.2 答案 24.8 练习 附录A 使用NetBeans IDE A.1 安装NetBeans A.2 创建新项目 A.3 创建新的Java类 A.4 运行应用程序 A.5 修复错误 附录B Java资源 B.1 可以考虑的其他书 B.2 Oracle公司的 Java官方站点 B.3 其他Java站点 B.3.1 本书英文版的配套网站 B.3.2 Café au Lait B.3.3 Workbench B.3.4 Java 7 Developer Blog B.3.5 其他Java博客 B.3.6 InformIT B.3.7 Stack Overflow B.3.8 Java Review Service B.3.9 JavaWorld杂志 B.3.10 Developer.com’s Java Directory 附录C 本书站点 附录D 设置Android开发环境 D.1 起步 D.2 安装Eclipse D.3 安装 Android SDK D.4 安装在Eclipse中使用的Android插件 D.5 设置你的手机 其他 版权

Java初级教程

Java入门经典
第22章 利用JAX-WS开发Web服务

本章介绍如下内容:

定义Web服务的Java接口;

将接口应用到Java类;

在Internet上部署Web服务;

查看Web服务合约;

开发Web服务客户端。

由于Internet无处不在,将数以百万计的桌面计算机、Web服务器、视频游戏机,以及其他设备互连起来的诉求,催生了Web服务。Web服务是一种经由HTTP(网络协议)与其他软件进行通信的软件。

Java 最激动人心的一个特性是用于 XML Web 服务的 Java API(JAX-WS)。JAX-WS 是一组Java类和Java包,它可以创建对Web服务发出请求的客户端,以及接受这些请求的服务。

JAX-WS 支持使用简单对象访问协议(Simple Object Access Protocol,SOAP)和表述性状态转移(Representational State Transfer,REST)实现的 Web 服务。JAX-WS 大大简化了支持这些协议的任务。作为一名程序员,你只需要创建Java对象,并调用方法来使用Web服务即可,其他事宜将在幕后进行处理。

22.1 定义服务端点接口

创建 JAX-WS Web 服务的第一步是创建服务端点接口(Service Endpoint Interface),这是一个Java接口,它定义了客户端在使用Web服务时能够调用的方法。

本章将要开发的 SquareRootServer Web 服可以处理两类简单的任务:

计算一个数的平方根;

显示当前的日期和时间。

接口是一组方法,它提供了名称、参数和返回类型,但是没有包含实现方法的代码。接口充当对象之间的合约:如果一个对象实现了该接口,其他对象就会知道它们可以调用该对象中接口的所有方法。

在第15章中,我们已经在任何这样的Java类中实现了ActionListener接口,即当有按钮被单击时,需要接收操作事件的Java类。

在这个项目中,我们要处理的是合约的其他方面。SquareRootServer 接口定义了 square Root(double)和 getTime( )这两个方法,而且这两个方法必须出现在实现了 Web 服务的类中。

下面的语句定义了接口:

在接口中定义方法时,跟在方法后面的是分号而不是将语句块括起来的“{”和“}”字符。接口中没有定义方法的行为,而是由实施了该接口的类来处理。

由于这些方法被称为 JAX-WS Web 服务,因此必须在每个方法前面添加一个额外的修饰词:@WebMethod注解。

使用注解来简化Java代码

注解(annotation)是一种巧妙的注释(comment)形式,可以被Java解释器、编译器和编程工具所理解。注解可以定义不属于程序一部分的程序信息,使得当程序在编译或运行时,这些程序信息能够触发行为。

注解使用@符号打头,后面是注解的名字。

最常见的一个注解是@Override,它表示一个方法覆盖了超类的方法。下面是一个例子:

如果期间有错误,则它不会覆盖方法,但是当使用了错误的类型或者参数个数不一致时,将发生错误,编辑器可以捕获该错误。

@WebMethod注解表示一个方法可以作为Web服务调用。SquareRootServer接口也使用了一个@WebService注解,来指示接口定义了一个服务端点接口。

注解也可以接受供将来自定义使用的参数。SquareRootServer 包含一个最终(final)注解:

该注解在Web服务和调用该服务的客户端程序之间定义了一个合约,本章后面将会详细介绍。

现在,开始编写 Web 服务的代码。在 NetBeans 中创建一个 Java 空文件,其类名为SquareRootServer,其包名为com.java24hours.ws。然后在该文件中输入程序清单22.1中的内容。

程序清单 22.1 SquareRootSever.java 的完整源代码

该类位于com.java24hours.ws包中,这样在部署Web服务之后,其他软件能够通过Internet轻松访问该服务。

完成接口的定义之后,开始编写实现接口两个方法(getSquareRoot( )和 getTime( ))的代码。

22.2 创建服务实现Bean

实现了服务端点接口的 Java 类被称为服务实现 Bean(Service Implementation Bean)。在JAX-WS的学习过程中,遇到一些新奇的术语是不可避免的。

SquareRootServerImpl类实现了SquareRootServer接口,如下所示:

这表示,你要创建的类必须包含接口中的所有方法,而且每一个都有适当的参数。

方法 getSquareRoot(double)和 getTime( )是使用前面学习的技术来实现的。

类中唯一比较新鲜的地方是后面的注解,它出现在类语句之前:

该注解表示,类是名为com.java24hours.ws.SquareRootSever的服务端点接口的服务实现Bean。你必须使用完整的类名,其中包括其包的名字。

注意,注解后面跟的不是分号,这与语句不同。

开始编写该类:在 com.java24hours.ws 包中创建一个名为 SquareRootServerImpl 的 Java空文件,然后输入程序清单22.2中的所有内容。

程序清单 22.2 SquareRootServerImpl.java 的完整源代码

在创建了这两个类之后,即可准备启用该服务,以便其他软件来调用。

警告:

服务实现Bean的名字源于JavaBeans,后者是一个特殊的Java类,在Java企业版中用作可重用的软件组件。然而,就JAX-WS而言,对Bean的命名有点不是很合适。任何Java对象,只要遵循Web服务方法和规则,而且创建时带有合适的注解,就可以作为服务实现Bean。

22.3 发布Web服务

JAX-WS Web 服务可以使用诸如 BEA WebLogic、GlassFish、JBoss 和 Jetty这样的 Java应用服务器来部署。如果在支持这些服务器的开发环境中创建了 SquareRootServer Web 服务,此时就可以准备启用Web服务。

你也可以自己编写Java应用程序,使其载入Web服务,并通过Internet向其他客户端提供服务。

SquareRootServerPublisher应用程序只需要两个步骤就可以处理该任务:

载入实现了Web服务的类;

将该对象发布到Internet。

javax.xml.ws 包中的 EndPoint 类有一个类方法 publish(String, Object),它可以部署 Web服务。

该方法的第一个参数是可以访问 Web 服务的网络地址,对该项目而言,该网络地址是http://127.0.0.1:5335/service。该网络地址以主机名 127.0.0.1 打头,这被称为本地主机,因为该主机是你创建并运行Java程序的本地计算机。

网络地址的第2部分是本地主机的端口号,Web服务在该端口号等待连接。这里使用的端口号是5335,因为该端口号不太可能被计算机上其他Internet感知(Internet-aware)程序使用。

地址的最后一部分“/service”是路径。每一个Web服务必须有一个唯一的路径。如果在你的计算机上运行其他Web服务,则它们的路径不能与SquareRootServer相同。

为了部署Web服务,在com.java24hours.ws包中创建一个名为SquareRootServerPublisher的Java空文件,然后输入程序清单22.3中的所有文本。

程序清单 22.3 SquareRootServerPublisher.java 的完整源代码

运行该程序时,它将在计算机上的5335端口等待连接。只要程序支持SOAP或基于REST的Web服务,则无论它是使用Java语言还是其他语言编写的,都可以调用其中的Web服务的方法。只要你的Web服务位于Internet中,任何连接到Internet的软件都可以调用其方法。

22.4 使用Web服务描述语言文件

在启用该Web服务之前,你可以使用任意的Web浏览器来测试SquareRootServerPublisher应用程序的可用性。

打开浏览器,然后输入地址 http://127.0.0.1:5335/service?wsd。该浏览器将显示程序清单22.4中的XML文件。该文件由刚才创建的应用程序提供。

该文件是一个使用 Web 服务描述语言(Web Service Description Language,WSDL)编写的服务合约,WSDL是一个XML方言,它可以清楚地说明Web服务的运行方式,以便服务器和客户端能够充分使用它。

在创建JAX-WX服务和客户端来访问Web服务时,没有必要必须理解WSDL。当然,最好还是看一下该文件的内容,以对基于SOAP和REST的Web服务的运行方式有一个理解。

程序清单 22.4 WSDL 合约

WSDL只所以称为服务合约,是因为它规定了访问Web服务的方式、可以与服务交换的信息,以及所传输信息的数据类型。

WSDL合约的第13~22行定义了Web服务的方法、这些方法的参数,以及作为响应返回的数据。查看这些代码行,看是否能够找到 getSquareRoot( )方法所在的位置。该方法接受一个double型参数,并返回一个double型值。

合约中提到的数据类型不是Java的数据类型,它们可以用于任何支持SOAP的编程语言(没有专门针对Java的Web服务)。

注意:

由于WSDL合约定义了Web服务的细节,因此可以使用它来自动完成 Web 服务编程的大部分过程。Java 开发工具包(JDK)包含命令行工具wsimport,它可以将WSDL文件作为输入,然后用于访问Web服务的Java类。

22.5 创建Web服务客户端

这一节将创建SquareRootClient应用程序,它可以调用你前面创建的Web服务的方法。当然,该服务必须处于运行状态,以便客户端与其连接。

由于像JAX-WS库这样的Web服务技术支持SOAP、REST、HTTP和XML等标准,因此不一定非要使用 Java 程序来连接该 Web 服务。Perl、Python、Ruby 和其他语言都有支持Web服务的库。

JAX-WS库在javax.xml.ws包中提供了Service类,这是一个可以创建调用Web服务的对象的工厂(factory)。

类方法Service.create(URL,QName)创建了工厂,其参数URL和QName分别来自java.net和java.xml.namespace。

URL必须是Web服务的WSDL合约的地址:

警告:

前面提到,URI不一定非要是一个可用的网络地址,尽管http://ws.java24 hours.com 看起来很像一个可用的网络地址,但是它是作为唯一的标识符出现的。我拥有域名 java24hours.com,并可以控制其子域名的使用方式,因此我将http://ws.java24hours.com作为URI使用。我可以保证其他Web服务提供商不会使用该标识符。

QName 是一个限定名称(qualified name),这是一个与 Web 服务提供者关联起来的 XML标识符。限定名称包含命名空间URI和本地的标识符。

命名空间URI和URL相似,但是不一定非要作为网络地址来使用。由于平方根Web服务的包名称是 com.java24hours.ws ,在 Java 中,按照惯例,该名称与 Internet 主机名ws.java24hours.com关联起来,用于该Web服务的命名空间URI是http://ws.java24hours.com。

该Web服务的本地标识符是服务实现Bean的名字,而且后面添加有“Service”单词。下面是一个创建限定名称的语句:

使用URL和限定名称则可以创建Web服务客户端工厂:

该工厂有getPort(Class)方法,这个方法创建了指定类的独享。为了对作为方法参数使用的Java类进行识别,可以使用名为class的类变量。感到困惑了?当在Java语句中看到它时,就会明白了:

使用SquareRootServer.class作为参数来调用getPort( )方法时,将导致工厂创建一个Square RootServer对象。该对象存储在src变量中。

可以在Java的其他对象中调用SquareRootServer对象的方法:

JAX-WS库将这些方法调用作为SOAP消息打包,然后通过Internet发送到Web服务,然后进行方法调用。

当服务响应这些调用时,它将响应打包为SOAP消息,然后通过Internet发送回去,之后再被转换为Java数据类型。

创建一个名为SquareRootClient的Java文件,然后输入程序清单22.5中的所有内容。

程序清单 22.5 SquareRootClient.java 的完整源代码

运行该客户端应用程序时,如果SquareRootPublisher应用程序也已经处于运行状态,则会看到图22.2中的输出。

图22.2 调用 Web 服务并显示响应

22.6 总结

在Java中,有一类API用作基于XML的RPC(JAX-RPC),JAX-PRC是一种允许Java对象经由Internet向另外一个对象进行远程过程调用(RPC)的技术。而JAX-WS包和类的集合则继承了该类API。

无论软件放在哪里,使用什么语言编写而成,都可以进行对其调用的能力在 Web 2.0 软件开发浪潮中具有重要的作用。

在20世纪90年代中期,网络开始流行之时,人们就已经享用到了Internet独一无二的连接优势,而 Web 2.0 则允许软件来采用这种连接优势。

本节讲解了使用JAX-Ws来创建和使用Web服务的4个步骤:为服务创建一个接口(服务端点接口)、实现该服务(服务实现Bean)、在Internet上发布服务,以及创建客户端访问该服务。

许多编程工具,包括NetBeans和JDK,都可以自动创建代码,从而简化创建和访问Web服务的工作。

22.7 问与答

问:XML-RPC 是如何应用于 SOAP Web 服务中的?

答:XML-PRC是一个协议,它可以通过HTTP来调用方法,并接收XML格式的数据。SOAP也是处理这些事情。事实上,这两个Web协议具有同一个起源。

XML-PRC 诞生于一份协议的草案中,而该协议最终成为 SOAP。由于 XML-RPC 先于SOAP 而生,其实现也早于 SOAP,因此它沿着自己的路进行发展,并且直到如今仍然广受欢迎。Apache XML-RPC Java 库(可以从 http://ws.appache.org/xmlrpc 下载),可以创建使用XML-RPC的Web服务和客户端。

而SOAP是一种更为复杂的Web服务协议,其支持的客户端/服务交互的范围更为广泛。

问:为什么com.java24hours.ws包与Internet主机ws.java24hours.com关联到一起?它们是如何关联的?

答:Java包的名字是由开发该包的程序员创建的。Oracle在给Java类库中的Java包命名时,使用java或javax打头,比如java.util和javax.swing。当其他程序员创建包时,他们遵循了一个惯例,以防止两个实体选择相同的包名称,以及防止两个实体相互混淆。

该惯例是,基于实体所拥有的域名来选择包的名字。由于我是域名cadenhead.org的拥有者,因此在创建Java类时,其包名可以以org.cadenhead开头,比如org.cadenhead.web。Apache软件基金会(Apache Software Foundation)拥有apache.org 域名,因此可以将它的 XML-RPC包命名为org.apache.xmlrpc。

22.8 测验

22.8.1 问题

1.服务实现Bean是什么?

a.一个接口,可以识别通过Web服务进行访问的方法。

b.实现了Web服务的类。

c.位于Web服务和调用该服务的客户端之间的服务合约。

2.当像@WebMethod或@Override这样的文本出现在方法声明中时,将调用什么?

a.注解。

b.断言。

c.恼怒。

3.WSDL代表什么?

a.Web 服务部署语言(Web Services Deployment Language)。

b.Web 服务描述语言(Web Services Description Language)。

c.Lucy in the Sky with Diamonds。

22.8.2 答案

1.b.答案a指的是服务端点接口。

2.a.尽管我觉得答案c也可能是真的,但是这取决于在这一节遇到了多大的麻烦。

3.b.WSDL 通常被错误地成为 Web 服务定义语言(Web Services Definition Language)。

22.9 练习

为了进一步巩固本节所学的知识,请做如下练习:

在平方根 Web 服务程序中添加一个方法,该方法将一个数乘以 10 ,然后修改SquareRootClient应用程序来调用该方法。

创建一个新的 Web 服务,它使用第 21 章中的 WeatherStation 类,而且通过该 Web服务可以访问当前的温度(高温、低温)、天气情况。

有关为完成这些练习而编写的Java程序,请访问本书的配套网站www.java24hours.com。

没有精选讨论主题。

全部讨论主题 查看精选主题

没有讨论主题。
😃 😅 😆 😁 😂 😊 😄 😠 😩 😲 😞 😵 😰 😒 😍 😤 😜 😝 😋 😘 😚 😷 😳 😢 😭 😨 😣 😡 😌 😖 😔 😱 😪 😏 😓 😥 😫 😉 👊 👍 👆 👇 👈 👉 👋 👏 👌 👎 👐 💓 💔 💕 💖 💗 💘 💙 💚 💛 💜 💝 💞 💟