现在的位置: 首页 > 综合 > 正文

使用 Eclipse 和 Java SE 6 创建独立 Web Services 应用程序,第 2 部分: Web 服务客户端应用程序

2017年12月24日 ⁄ 综合 ⁄ 共 10415字 ⁄ 字号 评论关闭

创建新项目

您也许还记得,在第 1 部分中,一个 Eclipse 项目包含应用程序的源代码和其他相关文件。可以使用项目作为源代码容器,或者在项目中创建文件夹,以便组织文件。为了创建 Web 服务客户端,需要创建一个新的项目:

  1. 选择 File > New > Project
  2. 展开 Java 文件夹并单击 Java Project(见图 1)。 

    图 1. 在 Eclipse 中创建项目
    在 Eclipse 中创建项目

  3. 单击 Next
  4. 根据提示输入项目名,例如 wsClientExample,如图 2 所示。 

    图 2. 在 Eclipse 中输入项目详细信息
    在 Eclipse 中输入项目详细信息

  5. 如果 Use default JRE 单选按钮之前已默认选中,则选择该单选按钮;否则选择 Use a project specific JRE 单选按钮,确保它是 Java SE 6。
  6. 单击 Finish 将项目与第 1 部分中安装的 Java JDK 相关联。
  7. 如果提示切换 Java 透视图,单击 Yes。 

    Eclipse 环境在 Package Explorer 中现在应该有两个项目,如图 3 所示。一个项目是在本教程第 1 部分中创建的,另一个项目是刚才创建的。 

    图 3. Eclipse 中的 Project Explorer
    Eclipse 中的 Project Explorer

  8. 右键单击 wsClientExample 项目下的 src 文件夹,然后选择菜单项 New > Package,为客户端应用程序包输入一个名称,例如 com.myfirst.wsClient,如图 4 所示。 

    图 4. 在 Eclipse 中创建包
    在 Eclipse 中创建包

生成 Web 服务客户端代码

为了创建客户端代码,需要运行 wsimport 任务。和在本系列第 1 部分中一样,您将从一个名为 build.xml 的 Ant 脚本中运行该任务:

  1. 右键单击项目,选择 New > File
  2. 输入名称 build.xml,然后单击 Finish(见图 5)。
  3. 右键单击该文件,选择 Open With > Ant Editor,在 Ant Editor 中打开该文件。从现在起,每当双击该文件,都会在 Ant Editor 中打开它。 

    图 5. 创建 build.xml 文件
    在 Eclipse 中创建项目

  4. 输入清单 1 中显示的 Ant 项目。 

    清单 1. Ant 脚本

    							
    <project default="wsimport">
    
      <target name="wsimport">
        	
        <exec executable="{java.home}/../bin/wsimport">
        		
          <arg line="-keep -s ./src -p com.myfirst.wsClient 
              -d ./bin http://localhost:8080/wsServerExample?wsdl"/>
        		
        </exec>
        	
      </target>
    
    </project>
    			

  5. 在运行 Ant build.xml 文件之前,必须首先回到第 1 部分 中创建的项目,并启动 RunService 服务。为此,展开该项目,右键单击 RunService 文件,选择 Run As > Java Application
  6. 确认 Eclipse IDE 控制台窗口显示消息说该服务已启动,如图 6 所示。 

    图 6. 服务运行时的控制台
    服务运行时的控制台

  7. 为了运行 Ant build.xml 文件,返回到本项目(wsClientExample),单击右键并选择 Run As > Ant Build,执行该 Ant 文件。
  8. 确认 Eclipse Console 窗口中显示一条 BUILD SUCCESSFUL 消息,如图 7 所示。 

    图 7. Ant Build Success
    Ant Build Success

  9. 返回到 Eclipse 项目,右键单击 wsClientExample 并选择 Refresh,或者选中项目并按 F5,刷新项目。现在在com.myfirst.wsClient 包下应该可以看到生成的运行客户端的代码(见图 8)。 

    图 8. 生成的代码
    生成的代码

在此过程中,wsimport 任务从运行 RunService 时发布的 WSDL 生成 JAX-WS 可移植工件。这就是服务必须首先运行的原因。

  • wsgen 读取服务端点类,并生成部署和调用 Web 服务所需的所有工件。
  • wsimport 读取 WSDL,并生成开发、部署和调用 web 服务所需的所有工件。

您将在下一节创建的客户端应用程序中使用这些生成的类。

创建客户端应用程序

现在,您已经生成了 Web 服务客户端的代码,接下来需要在 com.myfirst.wsClient 包下创建使用它的应用程序:

  1. 右键单击那个包,选择选项 New > Class,然后配置它,如图 9 所示。 

    图 9. 创建一个类
    创建一个类

  2. 将类创建为 public,类中有一个 main 方法。


提供了含有一个类的包之后,便可以开始编写客户端代码,如清单 2 所示。


清单 2. 客户端应用程序

					
package com.myfirst.wsClient;

import javax.xml.ws.BindingProvider;

public class SayHelloClient {

    public static void main(String args[]) {
		
        SayHelloService shs = new SayHelloService();
		
        SayHello sh = (SayHello) shs.getSayHelloPort();
		
        ((BindingProvider)sh)。getRequestContext()。put(BindingProvider.
            ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/wsServerExample");

        System.out.println( ((BindingProvider)sh)。toString() );

        System.out.println(sh.getGreeting("Fiona"));

    }
}

运行客户端应用程序

使用 Eclipse

编写客户端应用程序之后,试着在 Eclipse 中运行它:

  1. 右键单击 SayHelloClient.java,并选择 Run As > Java Application。这时应该会显示 Eclipse IDE 控制台窗口。如果没有显示控制台窗口,从菜单栏选择 Window > Show View > Console。此时应该可以看到执行 Web 客户端的结果,如图 10 所示。 

    图 10. 运行客户端应用程序
    运行客户端应用程序


当运行 SayHelloClient 应用程序时,它创建一个新服务 SayHelloService,它是由通过清单 1 中的 Ant 脚本运行的 wsimport 任务生成的类之一。然后,它获得端口 SayHello,这是调用目标服务端点上的操作的一个代理。然后,该客户端获得请求上下文,将端点地址 http://localhost:8080/wsServerExample 添加到上下文,这个上下文是用于处理请求消息的一个
map。这里有两条 print 语句,第一条以易于阅读的格式显示 SayHello,第二条显示返回的问候语 Hello Fiona(见图 10)。

完成时,可以通过在 Eclipse console 视图中终止 Web 服务来停止它。

使用脚本

为了脱离 Eclipse 运行,可以修改 wsClientExample 的 build.xml,使它在单独的 shell 窗口中启动服务器和客户端应用程序:

  1. 双击 build.xml 文件,在 Ant 编辑器中编辑它。
  2. 修改该文件,如清单 3 所示。 

    清单 3. 修改后的 build.xml 文件

    							
    <project default="runClient">
    
        <!-- ================================= 
                target: wsimport              
             ================================= -->
        <target name="wsimport" description="--> 
                Read the WSDL and generate the required artifacts">
            <exec executable="${java.home}/../bin/wsimport">
                <arg line="-keep -s ./src -p com.myfirst.wsClient -d ./bin 
                    http://localhost:8080/wsServerExample?wsdl"/>
            </exec>
        </target>
    
        <!-- ================================= 
                target: runServer              
             ================================= -->
        <target name="runServer" description="--> 
                Runs the Web service server from a terminal">
            <echo>
    Running the following command from the terminal to run the server:
    ${java.home}/bin/java -cp "${basedir}/../wsServerExample/bin" 
        com.myfirst.wsServer.RunService
           </echo>
            
            <exec dir="${java.home}/bin/" executable="cmd" spawn="true" 
            		os="Windows XP" description="runs on XP">
                <arg line="start cmd /K start cmd /K" />
                <arg line='${java.home}/bin/java -cp 
                	"${basedir}/../wsServerExample/bin" 
                	com.myfirst.wsServer.RunService' />
            </exec>
            
            <exec executable="xterm" spawn="true" os="Linux" 
                    description="Runs on Linux">
                <arg line="-e ${java.home}/bin/java -cp  
                	'${basedir}/../wsServerExample/bin' 
                	com.myfirst.wsServer.RunService"/>
            </exec>
        </target>
    
        <!-- ================================= 
                target: pause
             ================================= -->
        <target name="pause" depends="runServer" description="--> 
                Pauses briefly while the server starts">
            <sleep seconds="5"/>
        </target>
    	
        <!-- ================================= 
                target: runClient
             ================================= -->
        <target name="runClient" depends="pause" description="--> 
                Runs a Web service client from a terminal">
            <echo>
    Running the following command from the terminal to run the client:
    ${java.home}/bin/java -cp "${basedir}/bin" com.myfirst.wsClient.SayHelloClient
           </echo>
    
            <exec dir="${java.home}/bin/" executable="cmd" spawn="true" 
                    os="Windows XP" description="Runs on XP">
                <arg line="start cmd /K start cmd /K" />
                <arg line='${java.home}/bin/java -cp "${basedir}/bin" 
                    com.myfirst.wsClient.SayHelloClient' />
            </exec>
            
            <exec executable="xterm" spawn="true" os="Linux" 
                    description="Runs on Linux">
                <arg line="-hold -e ${java.home}/bin/java -cp '${basedir}/bin' 
                    com.myfirst.wsClient.SayHelloClient" />
            </exec>
        </target>
    
    </project>
    
    

注意:若要在 linux 上运行,必须首先设置 JAVA_HOME;在命令行输入:set JAVA_HOME=<your/java/home>

新的 build.xml 有两个新的目标:runServer 和 runClient。您可能已经注意到,第一行中还更新了 default 目标值,使之不运行wsimport 任务,而是运行 runClient 目标。而且,注意 runClient 对 pause 有依赖,这意味着虽然默认值为 runClient,但首先会运行
pause。pause 任务依赖于 runServer。这样便允许在客户端运行之前进行暂停,以便适当地启动服务器。所以 runServer 将首先运行。还有一点要注意的是 os 值。这个值表明将执行哪个操作系统(OS)命令,它由
Java Virtual Machine(JVM)决定。OS 是在os.name 系统属性中设置的。修改后的 build.xml 脚本只包括 Windows 和 Linux,但是必要时可以增加适合您环境的其他操作系统,并更改 Ant <exec> 任务。(请参阅 参考资料,了解更多关于
Ant 的信息)。

注意加粗的 <echo> 部分没有像其他行那样缩进。这是因为所有字符都会返回,包括空格字符。这意味着在 console 窗口中显示的消息将不会有前导空格(图 11)。当脚本运行时,它将显示可以从控制台运行的用于运行服务器应用程序的命令。

为了测试脚本的执行,可以对客户端应用程序作一些修改,以便可以运行它,直到退出。修改如下:

  1. 双击 SayHelloClient.java,编辑该文件,如以下清单所示: 

    清单 4. 修改后的 SayHelloClient.java 文件

    							
    package com.myfirst.wsClient;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    import javax.xml.ws.BindingProvider;
    import com.myfirst.wsClient.SayHello;
    import com.myfirst.wsClient.SayHelloService;
    
    public class SayHelloClient {
    
        public static void main(String[] args) {
    		
            SayHelloService shs = new SayHelloService();
            SayHello sh = (SayHello) shs.getSayHelloPort();
            ((BindingProvider) sh )。getRequestContext()。put(
                BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
                "http://localhost:8080/wsServerExample");
            System.out.println(((BindingProvider) sh)。toString());
    
            String userName = null;
            boolean exit = false;
            while (!exit) {
                System.out.print("\nPlease enter your name 
                    (type 'quit' to exit): ");
                BufferedReader br = new BufferedReader(
                    new InputStreamReader(System.in));
                try {
                    userName = br.readLine();
                } catch (IOException e) {
                    System.out.println("Error reading name.");
                    System.exit(1);
                }
                if (!(exit = userName.trim()。equalsIgnoreCase("quit") || 
                        userName.trim()。equalsIgnoreCase("exit"))) {
                    System.out.println(sh.getGreeting(userName));
                }
            }
            System.out.println("\nThank you for running the client.");
        }
    }
    
    

当客户端应用程序运行时,它将继续提示输入,直到输入 quit 或 exit。为了运行 Ant 脚本:

  1. 右键单击 build.xml,选择 Run As > Ant Build
  2. 确认 Eclipse Console 窗口出现一条 BUILD SUCCESSFUL 消息,如图 11 所示。 

    图 11. Ant 构建成功的消息以及返回的消息
    Ant 构建成功的消息以及返回的消息

执行 Ant 脚本后,应该会打开两个命令窗口,一个是服务器应用程序的窗口(见图 12),一个是客户端应用程序的窗口(见图 13)。客户端窗口不断提示输入姓名,直到退出应用程序。每当输入一个姓名,修改后的 SayHelloClient 应用程序通过一个 while循环进行迭代,在该循环中,它将输入的姓名发送到服务器,服务器则返回问候语,返回的问候语在窗口中显示为 Hello
<name>


图 12. 服务器的命令窗口
服务器的命令窗口 


图 13. 客户端的命令窗口
客户端的命令窗口 

在两个命令窗口中分别输入 “quit”,退出服务器和客户端 Java 应用程序,然后关闭每个命令窗口应用程序。

用 SOAP Monitor 监视通信

在 Eclipse 中配置 TCP/IP Monitor

至此,您已经创建了一个服务器和一个客户端,现在可以使用 Eclipse TCP/IP Monitor 监视 SOAP 传输。该监视器是一个简单的服务器,它监视服务器与客户端之间的所有请求和响应,如图 14 所示。


图 14. 服务器与客户端之间的 SOAP 传输
服务器与客户端之间的 SOAP 传输 

  1. 要查看该活动,需要选择 Window > Show View > Other > Debug > TCP/IP Monitor,从而打开 TCP/IP Monitor 视图,如图 15 所示。 

    图 15. 显示 TCP/IP Monitor
    显示 TCP/IP Monitor

该视图将出现在 Eclipse IDE 底部的面板中,如图 16 所示。


图 16. 查看 TCP/IP Monitor
查看 TCP/IP Monitor 


  1. 要配置 TCP/IP Monitor,可选择 Windows > Preferences,并展开 Run/Debug,然后单击 TCP/IP Monitor,如图 17 所示。

    图 17. 添加 TCP/IP Monitor
    添加 TCP/IP Monitor

从该窗口中(图 17),可以通过 Start 和 Stop 按钮管理表中列出的多个 TCP/IP 监视服务器。可以添加、编辑、移除、启动或停止可用的服务器。Status 列表明监视器是已启动还是已停止。

  1. 勾选窗口中的复选框,以便每当有活动时自动显示 TCP/IP Monitor 视图,然后单击 Add... 按钮定义一组新的配置选项,如图 17 所示。输入以下详细信息,如图 18 所示: 

    图 18. 配置 TCP/IP Monitor
    配置 TCP/IP Monitor

    选项描述

    • Local monitoring port 是本地计算机上一个唯一的端口号,例如 8081
    • Host name 是用于运行服务器的计算机的计算机名或 IP 地址,例如 localhost
    • Port 是远程服务器的端口号,例如 8080
    • Type 是从浏览器发送的请求类型,有 HTTP 和 TCP/IP 两种选项。
    • Communication Timeout 是与服务器的 TCP/IP 连接可持续的时间长度,单位为毫秒。

  1. 单击 OK 保存更改。

更新客户端代码

接下来,需要对客户端代码作一些更改,以便通过 TCP/IP monitor 重定向 Web 服务。这里需要更改 Web 服务的端点,因为 TCP/IP monitor 侦听端口 8081。更新后的代码如清单 5 所示:


清单 5. 客户端应用程序

					
      
package com.myfirst.wsClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.xml.ws.BindingProvider;
import com.myfirst.wsClient.SayHello;
import com.myfirst.wsClient.SayHelloService;

public class SayHelloClient {

    public static void main(String[] args) {
		
        SayHelloService shs = new SayHelloService();
        SayHello sh = (SayHello) shs.getSayHelloPort();
        ((BindingProvider) sh )。getRequestContext()。put(
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
            "http://localhost:8081/wsServerExample");
        System.out.println(((BindingProvider) sh)。toString());

        String userName = null;
        boolean exit = false;
        while (!exit) {
            System.out.print("\nPlease enter your name 
                (type 'quit' to exit): ");
            BufferedReader br = new BufferedReader(
                new InputStreamReader(System.in));
            try {
                userName = br.readLine();
            } catch (IOException e) {
                System.out.println("Error reading name.");
                System.exit(1);
            }
            if (!(exit = userName.trim()。equalsIgnoreCase("quit") || 
                    userName.trim()。equalsIgnoreCase("exit"))) {
                System.out.println(sh.getGreeting(userName));
            }
        }
        System.out.println("\nThank you for running the client.");
    }
}    


运行 Web 服务

再次运行 Ant 脚本:右键单击之前创建的用于运行服务器和客户端的 build.xml,并选择 Run As > Ant Build

此时再次出现两个命令窗口,一个是服务器窗口,一个是客户端窗口。和之前一样,输入姓名。

查看 TCP/IP Monitor 视图,该视图看上去应该和下面的图 19 类似:


图 19. TCP/IP Monitor 的结果
TCP/IP Monitor 的结果 

在该视图中可以看到通过 TCP/IP Monitor 路由的请求和响应对。为了观察得更仔细,清单 6 和 7 显示了完整的头部:


清单 6. 请求头部

					
     
POST /wsServerExample HTTP/1.1
SOAPAction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: text/xml; charset=utf-8
User-Agent: Java/1.6.0
Host: localhost:8081
Connection: keep-alive
Content-Length: 226

<?xml version="1.0" encoding="UTF-8"?>
  <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <ns2:getGreeting xmlns:ns2="http://wsServer.myfirst.com/">
      <arg0>Fiona</arg0>
    </ns2:getGreeting>
  </S:Body>
  </S:Envelope>



清单 7. 响应头部

					
     
HTTP/1.1 200 OK
Content-type: text/xml; charset=utf-8
Transfer-encoding: chunked

fc
<?xml version="1.0" encoding="UTF-8"?>
  <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <ns2:getGreetingResponse xmlns:ns2="http://wsServer.myfirst.com/">
      <return>Hello Fiona</return>
    </ns2:getGreetingResponse>
  </S:Body>
  </S:Envelope>
0


可以看到,请求头部信封中加粗的部分是在客户端应用程序的命令窗口中输入的内容,此处为 Fiona。现在看看响应头部信封,可以看到返回的响应,此处为 Hello Fiona

可选活动

可以通过单击图 19 中用红色圈住的图标,确认 Web 服务 SOAP 传输是否遵从 WS-I。这将提示您保存一个日志文件,之后要验证该文件是否遵从 WS-I。可以在 XML 编辑器中打开该日志,查看它的内容。

结束语

创建、生成和发布 Web 服务服务器非常简单,只需使用 Eclipse 和 Java SE 6。借助过这些工具可以轻松地开发简单的 Web Services 服务器端和客户端应用程序。

抱歉!评论已关闭.