开发 JAX-WS Web 服务客户端

在本教程中,您将使用 NetBeans IDE 提供的 Web 服务工具来分析拼写检查器 Web 服务,然后构建一个与该服务交互的 Web 客户端。该客户端使用一个 Servlet 类和 Web 页。用户将信息从 Web 页传送到 Servlet。

目录

  • 使用拼写检查器 Web 服务

    • 创建客户端
    • 开发客户端
      • 编码 Web 页
      • 创建拼写检查器 Servlet 并对其进行编码
    • 部署客户端
  • 异步 Web 服务客户端
    • 创建 Swing 窗体
    • 启用异步客户端
    • 添加异步客户端代码
  • 应用所学知识

要学习本教程,您需要具备以下软件和资源。

软件或资源 要求的版本
NetBeans IDE Java EE 下载包
Java 开发工具包 (JDK) 版本 7 或版本 8
符合 Java EE 规范的 Web 服务器或应用服务器 Tomcat Web Server 7.0 
GlassFish Server Open Source Edition
Oracle WebLogic Server

注:如果使用的是 JDK 6,则需要 JDK 6 Update 7 或更高版本。

Tomcat 和 GlassFish Server 都可以随同 NetBeans IDE 的 Web 和 Java EE 分发一起安装。此外,也可以访问 GlassFish Server 下载页或 Apache Tomcat 下载页。

重要说明:Java EE 项目需要使用 Tomcat 7.x、GlassFish Server 或 Oracle WebLogic Server 12c。

下面显示了您将创建的客户端的外观,其中的所有数据都是从 Web 服务接收到的:

当学完本教程时,您会发现对于此应用程序,您只需提供要检查的文本,调用 Web 服务上的操作以及呈现结果。IDE 会生成联系 Web 服务以及发送文本所需的全部代码。其余的操作则由拼写检查器 Web 服务来完成。它将标识拼错的单词并提供建议的替代项列表。

本教程中使用的拼写检查器 Web 服务是由 CDYNE 公司提供的。CDYNE 旨在开发、销售并支持一整套数据增强、数据质量和数据分析 Web 服务以及商业智能集成。拼写检查器 Web 服务是 CDYNE 提供的一个 Web 服务。请注意,基于一个或多个 Web 服务的应用程序的功能大小取决于这些 Web 服务的可用性和可靠性。但是,CDYNE 在常见问题解答中指出,它有一个 100% 可用性目标,并且在发生自然灾害、恐怖行为或其他灾难性事件时,Web 服务流量会传输到其辅助数据中心。CDYNE 在编写本教程以及开发 NetBeans 方面给予了大力支持,NetBeans 要在此特别向其表示感谢。

使用拼写检查器 Web 服务

要通过网络使用名为 "consuming" 的 Web 服务,需要创建一个 Web 服务客户端。为了便于创建 Web 服务客户端,NetBeans IDE 提供了一个客户端创建工具,即“Web 服务客户端”向导,利用该向导可以生成用于查找 Web 服务的代码。此外,IDE 还提供了用于对所创建的 Web 服务客户端进行开发的工具,即 "Projects"(项目)窗口中包含节点的工作区域。这些工具包含在 NetBeans IDE 安装的 EE 包中。这些工具为即用型,无需任何插件。

创建客户端

在此部分,您将利用向导生成基于 Web 服务 WSDL 文件的 Java 对象。

  1. 选择 "File"(文件)> "New Project"(新建项目)(在 Windows 和 Linux 中为 Ctrl-Shift-N 组合键,在 MacOS 上为 ⌘-Shift-N 组合键)。在 "Categories"(类别)下,选择 "Java Web"。在 "Projects"(项目)下选择 "Web Application"(Web 应用程序)。单击 "Next"(下一步)。将项目命名为 SpellCheckService,然后确保将相应的服务器指定为目标服务器。(有关详细信息,请参考“入门指南”一节。)将其他所有选项保留为默认设置,然后单击 "Finish"(完成)。
  2. 在 "Projects"(项目)窗口中,右键单击 SpellCheckService 项目节点,选择 "New"(新建)> "Other"(其他),然后在 "New File"(新建文件)向导的 "Web Services"(Web 服务)类别中选择 "Web Service Client"(Web 服务客户端)。单击 "Next"(下一步)。
  3. 选择 "WSDL URL" 并为 Web 服务指定以下 URL:

    http://wsf.cdyne.com/SpellChecker/check.asmx?wsdl

    如果您处于防火墙的保护下,可能需要指定代理服务器,否则将无法下载 WSDL 文件。要指定代理服务器,请在向导中单击 "Set Proxy"(设置代理)。IDE 的 "Options"(选项)窗口将会打开,在此可为 IDE 设置普遍接受的代理。

  4. 将包名保留为空。默认情况下,将从 WSDL 中获取客户端类包名。在本例中为 com.cdyne.ws。单击 "Finish"(完成)。
  5. 在 "Projects"(项目)窗口的 "Web Service References"(Web 服务引用)节点中,您将看到以下内容: 

"Projects"(项目)窗口显示了一个名为 "check" 的 Web 服务,可以对应用程序执行多次 "CheckTextBody" 和 "CheckTextBodyV2" 操作。这些操作用于检查字符串是否存在拼写错误,并返回要由客户端处理的数据。该服务的 V2 版本不需要身份验证。在本教程中,将使用 checkSoap.CheckTextBodyV2 操作。

在 Generated Sources(生成的源文件)节点中,您将看到由 JAX-WS“Web 服务客户端”向导生成的客户端桩模块。

展开 "WEB-INF" 节点及其 "wsdl" 子节点。您将看到 WSDL 文件的本地副本,其名称为 check.asmx.wsdl

用于创建客户端的 WSDL 的 URL 已在 jax-ws-catalog.xml 中映射到 WSDL 的本地副本。映射到本地副本有几个好处。首先,客户端无需 WSDL 的远程副本即可运行。其次,客户端运行速度将会加快,因为其不需要对远程 WSDL 文件进行解析。最后,更加易于移植。

开发客户端

您可以通过多种方法来实现 Web 服务客户端。Web 服务的 WSDL 文件限制了您可以向该 Web 服务发送的信息类型,以及您从该 Web 服务接收的信息类型。但是,WSDL 文件不限制您对其所需信息进行传递的方式,以及用户界面所包含的内容。您接下来要构建的客户端实现包含一个 Web 页和一个 Servlet,前者可使用户输入要检查的文本,后者可将这些文本传递至 Web 服务,然后构建一个包含结果的报告。

编码 Web 页

Web 页将包含一个文本区域和一个按钮,前者可供用户输入文本,后者用于将该文本发送至 Web 服务。根据您选择作为目标服务器的服务器版本不同,IDE 生成了 index.html 或index.jsp 作为应用程序的索引页。

  1. 在 "Projects"(项目)窗口中,展开 SpellCheckService 项目的 "Web Pages"(Web 页)节点,然后双击索引页(index.html 或 index.jsp)以在源代码编辑器中打开文件。
  2. 将以下代码复制并粘贴到索引页的 <body> 标记中:
    <body><form name="Test" method="post" action="SpellCheckServlet"><p>Enter the text you want to check:</p><p><p><textarea rows="7" name="TextArea1" cols="40" ID="Textarea1"></textarea></p><p><input type="submit" value="Spell Check" name="spellcheckbutton"></form>
    </body>

    上面列出的代码指定当单击提交按钮时,textarea 的内容将被发送至名为 SpellCheckServlet 的 Servlet。

创建 Servlet 并对其进行编码

在此部分,您将创建一个与 Web 服务交互的 Servlet。但是,执行交互的代码将由 IDE 提供。因此,您只需处理业务逻辑,即,准备要发送的文本以及对结果进行处理。

  1. 在 "Projects"(项目)窗口中,右键单击 SpellCheckService 项目节点,选择 "New"(新建)> "Other"(其他),然后选择 "Web" > "Servlet"。单击 "Next"(下一步)以打开 "New Servlet"(新建 Servlet)向导。
  2. 将 Servlet 命名为 SpellCheckServlet,然后在 "Package"(包)下拉列表中键入 clientservlet。单击 "Next"(下一步)。
  3. 在 "Configure Servlet Deployment"(配置 Servlet 部署)面板中,注意此 Servlet 的 URL 映射是 /SpellCheckServlet。接受默认值,然后单击 "Finish"(完成)。该 Servlet 将在源代码编辑器中打开。 
  4. 将光标置于源代码编辑器中的 SpellCheckServlet.java 的 processRequest 方法主体内,并在该方法的顶部添加一些新行。
  5. 右键单击上一步所创建的空白区域,然后选择 "Insert Code"(插入代码)> "Call Web Service Operation"(调用 Web 服务操作)。在 "Select Operation to Invoke"(选择要调用的操作)对话框中,单击 checkSoap.CheckTextBodyV2 操作,如下所示: 

    单击 "OK"(确定)。

    注:您也可以将此操作节点直接从 "Projects"(项目)窗口拖放至编辑器中,而不调用以上所示的对话框。

    在 SpellCheckServlet 类的末尾,将会看到一个用于调用 SpellCheckerV2 服务并返回 com.cdyne.ws.DocumentSummary 对象的私有方法。

    private DocumentSummary checkTextBodyV2(java.lang.String bodyText) {com.cdyne.ws.CheckSoap port = service.getCheckSoap();return port.checkTextBodyV2(bodyText);
    }

    只需使用此方法即可调用 Web 服务上的操作。此外,还需在类的顶部声明以下代码行(粗体显示):

    public class SpellCheckServlet extends HttpServlet {@WebServiceRef(wsdlLocation = "http://wsf.cdyne.com/SpellChecker/check.asmx?WSDL")private Check service;
  6. 将 processRequest() 方法的 try 块替换为以下代码。以下代码行中的注释说明了每行代码的用途。
    try (PrintWriter out = response.getWriter()) {
        //Get the TextArea from the web pageString TextArea1 = request.getParameter("TextArea1");//Initialize WS operation argumentsjava.lang.String bodyText = TextArea1;//Process resultcom.cdyne.ws.DocumentSummary doc = checkTextBodyV2(bodyText);String allcontent = doc.getBody();//From the retrieved document summary,//identify the number of wrongly spelled words:int no_of_mistakes = doc.getMisspelledWordCount();//From the retrieved document summary,//identify the array of wrongly spelled words:List allwrongwords = doc.getMisspelledWord();out.println("<html>");out.println("<head>");//Display the report's name as a title in the browser's titlebar:out.println("<title>Spell Checker Report</title>");out.println("</head>");out.println("<body>");//Display the report's name as a header within the body of the report:out.println("<h2><font color='red'>Spell Checker Report</font></h2>");//Display all the content (correct as well as incorrectly spelled) between quotation marks:out.println("<hr><b>Your text:</b> \"" + allcontent + "\"" + "<p>");//For every array of wrong words (one array per wrong word),//identify the wrong word, the number of suggestions, and//the array of suggestions. Then display the wrong word and the number of suggestions and//then, for the array of suggestions belonging to the current wrong word, display each//suggestion:for (int i = 0; i < allwrongwords.size(); i++) {String onewrongword = ((Words) allwrongwords.get(i)).getWord();int onewordsuggestioncount = ((Words) allwrongwords.get(i)).getSuggestionCount();List allsuggestions = ((Words) allwrongwords.get(i)).getSuggestions();out.println("<hr><p><b>Wrong word:</b><font color='red'> " + onewrongword + "</font>");out.println("<p><b>" + onewordsuggestioncount + " suggestions:</b><br>");for (int k = 0; k < allsuggestions.size(); k++) {String onesuggestion = (String) allsuggestions.get(k);out.println(onesuggestion);}}//Display a line after each array of wrong words:out.println("<hr>");//Summarize by providing the number of errors and display them:out.println("<font color='red'><b>Summary:</b> " + no_of_mistakes + " mistakes (");for (int i = 0; i < allwrongwords.size(); i++) {String onewrongword = ((Words) allwrongwords.get(i)).getWord();out.println(onewrongword);}out.println(").");out.println("</font>");out.println("</body>");out.println("</html>");}
    
  7. 您会看到许多错误线和警告图标,指示未找到的类。要在粘贴代码之后修复导入,请按 Ctrl-Shift-I 组合键(在 Mac 上按 ⌘-Shift-I 组合键),或在任意位置单击鼠标右键,然后在打开的上下文菜单中选择 "Fix Imports"(修复导入)。(您可以选择要导入的 List 类。此处将接受默认的 java.util.List。)以下是已导入类的完整列表:
    import com.cdyne.ws.Check;
    import com.cdyne.ws.Words;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.xml.ws.WebServiceRef;

    注:如果看到“找不到 com.cdyne.* 类”的警告内容,请不要担心。当构建项目后,IDE 在解析 WSDL 文件并查找类时,此问题会得到解决。

    请注意,尚未处理上面列出的代码中存在的错误。有关详细信息,请参见应用所学知识。

部署客户端

IDE 使用 Ant 构建脚本来构建和运行应用程序。此构建脚本是由 IDE 基于您在创建项目时所输入的选项来构建的。您可以在项目的 "Project Properties"(项目属性)对话框(在 "Projects"(项目)窗口中右键单击项目节点,然后选择 "Properties"(属性))中调整这些选项。

  1. 右键单击项目节点,然后选择 "Run"(运行)。稍后,应用程序将部署并显示上一部分所编码的 Web 页。
  2. 输入一些文本,确保其中的某些文本存在拼写错误: 
  3. 单击 "Spell Check",然后查看结果: 

异步 Web 服务客户端

默认情况下,NetBeans IDE 创建的 JAX-WS 客户端是同步的。同步客户端会调用对服务的请求,然后在等待响应时挂起其处理。但是,在某些情况下,您希望客户端继续一些其他处理而不是等待响应。例如,在某些情况下,服务可能需要大量时间来处理请求。继续处理而不等待服务响应的 Web 服务客户端称为“异步”。

异步客户端会发出服务请求,然后继续其处理而不等待响应。服务会处理客户端请求,然后在一段时间后返回响应,而客户端则在这段时间内检索响应并继续其处理。

异步客户端会通过“轮询”或“回调”方法使用 Web 服务。在“轮询”方法中,将调用一个 Web 服务方法并反复请求结果。“轮询”是一种阻止操作,因为它会阻止调用线程,所以这就是不在 GUI 应用程序中使用它的原因。在“回调”方法中,您在 Web 服务方法调用期间传递回调处理程序。当结果有效时,将调用该处理程序的 handleResponse() 方法。这种方法适用于 GUI 应用程序,因为您不必等待响应。例如,从 GUI 事件处理程序发出调用并立即返回控制权,这样可以使用户界面随时保持响应。轮询方法的缺点是,即使在捕获响应后使用响应,也必须对其进行轮询来查明已将其捕获。

在 NetBeans IDE 中,通过勾选 Web 服务引用的编辑 Web 服务属性 GUI 中的框,将异步客户端的支持添加到 Web 服务客户端应用程序中。除了具有轮询 Web 服务或传递回调处理程序并等待结果的方法外,开发该客户端的所有其他方面都与同步客户端相同。

此部分的其余内容详述了如何创建 Swing 图形界面并将异步 JAX-WS 客户端嵌入其中。

创建 Swing 窗体

在此部分,您将设计 Swing 应用程序。如果不愿意自己设计 Swing GUI,可以下载预先设计的 JFrame,然后转至创建异步客户端中的此部分内容。

Swing 客户端会获取您键入的文本,将其发送至服务,然后返回错误数和所有错误词语的列表。该客户端还会向您显示每个错误词语和替换该词语的建议,一次只显示一个错误词语。

创建 Swing 客户端:

  1. 创建新的 Java 应用程序项目。将其命名为 AsynchSpellCheckClient。不要为该项目创建 Main 类。
  2. 在 "Projects"(项目)视图中,右键单击 AsynchSpellCheckClient 项目节点并选择 "New"(新建)> "JFrame Form..."(JFrame 窗体...)。
  3. 将该窗体命名为 MainForm,然后将其放置在包 org.me.forms 中。
  4. 创建 JFrame 后,打开项目属性。在 "Run"(运行)类别中,将 MainForm 设置为主类。 
  5. 在编辑器中,打开 MainForm.java 的 "Design"(设计)视图。在组件面板中,将三个滚动窗格拖放至 MainForm 中。定位滚动窗格并调整其大小。这些窗格将包含要进行检查所键入的文本、所有错误词语以及对某个错误词语提出的建议的文本字段。
  6. 将五个文本字段拖放至 MainForm 中。将其中的三个拖放至三个滚动窗格中。按如下方式对其进行修改:
    文本字段
    变量名称 在滚动窗格中? 可编辑?
    tfYourText Y Y
    tfNumberMistakes N N
    tfWrongWords Y N
    tfWrongWord1 N N
    tfSuggestions1 Y N
  7. 将进度栏拖放至 MainForm 中。将该变量命名为 pbProgress
  8. 将两个按钮拖放至 MainForm 中。将第一个按钮命名为 btCheck,并将其文本更改为 "Check Text" 或 "Check Spelling"。将第二个按钮命名为 btNextWrongWord,将其文本更改为 "Next Wrong Word",然后禁用该按钮。
  9. 将一些标签拖放至 MainForm 中,为应用程序提供一个标题并描述文本字段。

将 JFrame 的外观按您喜欢的方式进行排列,然后进行保存。接下来将添加 Web 服务客户端功能。

启用异步客户端

如创建客户端中所述,添加 Web 服务引用。然后编辑 Web 服务属性以启用异步客户端。

  1. 在 "Projects"(项目)窗口中,右键单击 AsynchSpellCheckClient 项目节点,然后选择 "New"(新建)> "Other"(其他)。在新建文件向导中,选择 "Web Services"(Web 服务)> "Web Service Client"(Web 服务客户端)。在“Web 服务客户端”向导中,指定 Web 服务的 URL:

    http://wsf.cdyne.com/SpellChecker/check.asmx?wsdl。接受所有默认值,然后单击 "Finish"(完成)。这与创建客户端中所述步骤 2 以后的过程相同。

  2. 展开 "Web Service References"(Web 服务引用)节点,然后右键单击 check 服务。上下文菜单打开。
  3. 从上下文菜单中选择 "Edit Web Service Attributes"(编辑 Web 服务属性)。“Web 服务属性”对话框打开。
  4. 选择 "WSDL Customization"(WSDL 定制”)签。
  5. 展开 "Port Type Operations"(端口类型操作)节点。展开第一个 CheckTextBodyV2 节点并选择 "Enable Asynchronous Client"(启用异步客户端)。 
  6. 单击 "OK"(确定)。该对话框关闭,并出现一条警告,指出更改 Web 服务属性将会刷新客户端节点。
  7. 单击 "OK"(确定)。该警告信息关闭,并刷新客户端节点。如果展开 "Web Service References"(Web 服务引用)中的 check 节点,则会看到现在已具有 CheckTextBody 操作的 "Polling"(轮询)和 "Callback"(回调)版本。

现已为您的应用程序启用了 SpellCheck 服务的异步 Web 服务客户端。

添加异步客户端代码

现在,您已经有了异步 Web 服务操作,可将其中一个异步操作添加到 MainForm.java 中。

添加异步客户端代码:

  1. 在 MainForm 中,切换到 "Source"(源)视图,然后将以下方法添加到最后一个右花括号的前面。

    public void callAsyncCallback(String text){}
  2. 在 "Projects"(项目)窗口中,展开 AsynchSpellCheckClient 的 "Web Service References"(Web 服务引用)节点,并找到 checkSoap.CheckTextBodyV2 [Asynch Callback] 操作。
  3. 将 CheckTextBodyV2 [Asynch Callback] 操作拖至空的 callAsyncCallback 方法主体中。IDE 会生成以下 try 块。将此生成的代码与为同步客户端生成的代码进行比较。
    try { // Call Web Service Operation(async. callback)com.cdyne.ws.Check service = new com.cdyne.ws.Check();com.cdyne.ws.CheckSoap port = service.getCheckSoap();// TODO initialize WS operation arguments herejava.lang.String bodyText = "";javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response> asyncHandler = new javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response>() {public void handleResponse(javax.xml.ws.Response<com.cdyne.ws.CheckTextBodyV2Response> response) {try {// TODO process asynchronous response hereSystem.out.println("Result = "+ response.get());} catch(Exception ex) {// TODO handle exception}}};java.util.concurrent.Future<? extends java.lang.Object> result = port.checkTextBodyV2Async(bodyText, asyncHandler);while(!result.isDone()) {// do somethingThread.sleep(100);}} catch (Exception ex) {// TODO handle custom exceptions here
    }

    在此代码与 Web 服务调用中,您会看到来自 SpellCheck 服务的响应是通过 AsynchHandler 对象进行处理的。同时,Future 对象会查看是否已返回了结果,然后使线程休眠直至完全返回了结果。

  4. 切换回 "Design"(设计)视图。双击 "Check Spelling" 按钮。IDE 会自动将 "ActionListener" 添加到按钮中,然后切换到 "Source"(源)视图中,光标同时出现在空的btCheckActionPerformed 方法中。
  5. 将以下代码添加至 btCheckActionPerformed 方法主体。此代码会获取您在 tfYourText 字段中键入的文本,使进度栏显示 "waiting for server" 消息,并禁用 btCheck 按钮,以及调用异步回调方法。
    private void btCheckActionPerformed(java.awt.event.ActionEvent evt) {                                        String text = tfYourText.getText();pbProgress.setIndeterminate(true);pbProgress.setString("waiting for server");btCheck.setEnabled(false);callAsyncCallback(text);
    }
  6. 在 MainForm 类的开头,实例化名为 nextWord 的私有 ActionListener 字段。此 ActionListener 字段是为 Next Wrong Word 按钮提供的,使用该按钮可以前进到错误词语列表中的下一个错误词语,并显示该词语以及更正它的建议。您可以在此处创建私有字段,这样就可以在定义了 ActionListener 的情况下取消对其的注册。否则,每次检查新文本时,都将添加一个额外的监听程序并最终出现多个监听程序多次调用 actionPerformed() 的情况。这样,该应用程序将无法正常运行。
    public class MainForm extends javax.swing.JFrame {private ActionListener nextWord;...
  7. 将整个 callAsyncCallback 方法替换为以下代码。请注意,最外层的 try 块已删除。此代码块是多余的,因为已在方法内添加了更多特定的 try 块。并且在代码注释中介绍了对代码所做的其他更改。 
    public void callAsyncCallback(String text) {com.cdyne.ws.Check service = new com.cdyne.ws.Check();com.cdyne.ws.CheckSoap port = service.getCheckSoap();// initialize WS operation arguments herejava.lang.String bodyText = text;javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response> asyncHandler = new javax.xml.ws.AsyncHandler<com.cdyne.ws.CheckTextBodyV2Response>() {public void handleResponse(final javax.xml.ws.Response<com.cdyne.ws.CheckTextBodyV2Response> response) {SwingUtilities.invokeLater(new Runnable() {public void run() {try {// Create a DocumentSummary object containing the response.// Note that getDocumentSummary() is called from the Response object// unlike the synchronous client, where it is called directly from// com.cdyne.ws.CheckTextBodycom.cdyne.ws.DocumentSummary doc = response.get().getDocumentSummary();//From the retrieved DocumentSummary,//identify and display the number of wrongly spelled words:final int no_of_mistakes = doc.getMisspelledWordCount();String number_of_mistakes = Integer.toString(no_of_mistakes);tfNumberMistakes.setText(number_of_mistakes);// Check to see if there are any mistakesif (no_of_mistakes > 0) {//From the retrieved document summary,//identify the array of wrongly spelled words, if any:final List<com.cdyne.ws.Words> allwrongwords = doc.getMisspelledWord();//Get the first wrong wordString firstwrongword = allwrongwords.get(0).getWord();//Build a string of all wrong words separated by commas, then display this in tfWrongWordsStringBuilder wrongwordsbuilder = new StringBuilder(firstwrongword);for (int i = 1; i < allwrongwords.size(); i++) {String onewrongword = allwrongwords.get(i).getWord();wrongwordsbuilder.append(", ");wrongwordsbuilder.append(onewrongword);}String wrongwords = wrongwordsbuilder.toString();tfWrongWords.setText(wrongwords);//Display the first wrong wordtfWrongWord1.setText(firstwrongword);//See how many suggestions there are for the wrong wordint onewordsuggestioncount = allwrongwords.get(0).getSuggestionCount();//Check to see if there are any suggestions.if (onewordsuggestioncount > 0) {//Make a list of all suggestions for correcting the first wrong word, and build them into a String.//Display the string of concactenated suggestions in the tfSuggestions1 text fieldList<String> allsuggestions = ((com.cdyne.ws.Words) allwrongwords.get(0)).getSuggestions();String firstsuggestion = allsuggestions.get(0);StringBuilder suggestionbuilder = new StringBuilder(firstsuggestion);for (int i = 1; i < onewordsuggestioncount; i++) {String onesuggestion = allsuggestions.get(i);suggestionbuilder.append(", ");suggestionbuilder.append(onesuggestion);}String onewordsuggestions = suggestionbuilder.toString();tfSuggestions1.setText(onewordsuggestions);} else {// No suggestions for this mistaketfSuggestions1.setText("No suggestions");}btNextWrongWord.setEnabled(true);// See if the ActionListener for getting the next wrong word and suggestions// has already been defined. Unregister it if it has, so only one action listener// will be registered at one time.if (nextWord != null) {btNextWrongWord.removeActionListener(nextWord);}// Define the ActionListener (already instantiated as a private field)nextWord = new ActionListener() {//Initialize a variable to track the index of the allwrongwords listint wordnumber = 1;public void actionPerformed(ActionEvent e) {if (wordnumber < no_of_mistakes) {// get wrong word in index position wordnumber in allwrongwordsString onewrongword = allwrongwords.get(wordnumber).getWord();//next part is same as code for first wrong wordtfWrongWord1.setText(onewrongword);int onewordsuggestioncount = allwrongwords.get(wordnumber).getSuggestionCount();if (onewordsuggestioncount > 0) {List<String> allsuggestions = allwrongwords.get(wordnumber).getSuggestions();String firstsuggestion = allsuggestions.get(0);StringBuilder suggestionbuilder = new StringBuilder(firstsuggestion);for (int j = 1; j < onewordsuggestioncount; j++) {String onesuggestion = allsuggestions.get(j);suggestionbuilder.append(", ");suggestionbuilder.append(onesuggestion);}String onewordsuggestions = suggestionbuilder.toString();tfSuggestions1.setText(onewordsuggestions);} else {tfSuggestions1.setText("No suggestions");}// increase i by 1wordnumber++;} else {// No more wrong words! Disable next word button// Enable Check buttonbtNextWrongWord.setEnabled(false);btCheck.setEnabled(true);}}};// Register the ActionListenerbtNextWrongWord.addActionListener(nextWord);} else {// The text has no mistakes// Enable Check buttontfWrongWords.setText("No wrong words");tfSuggestions1.setText("No suggestions");tfWrongWord1.setText("--");btCheck.setEnabled(true);}} catch (Exception ex) {ex.printStackTrace();}// Clear the progress barpbProgress.setIndeterminate(false);pbProgress.setString("");}});}};java.util.concurrent.Future result = port.checkTextBodyV2Async(bodyText, asyncHandler);while (!result.isDone()) {try {//Display a message that the application is waiting for a response from the servertfWrongWords.setText("Waiting...");Thread.sleep(100);} catch (InterruptedException ex) {Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);}}
    }
  8. 按 Ctrl-Shift-I 组合键(在 Mac 上按 ⌘-Shift-I 组合键)并修复导入。这样会添加以下 import 语句:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.List;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.SwingUtilities;

现在,您可以构建并运行应用程序了!遗憾的是,您不可能在获取服务器响应的很长延迟时间里看到所发生的变化,因为服务的处理速度相当快。

应用所学知识

现在,您已在 IDE 中创建了第一个 Web 服务客户端,接下来该您大显身手,对应用程序进行全方位扩展了。下面建议了两项可着手执行的任务。

  • 在 Servlet 中添加错误处理代码。
  • 重写客户端,以使用户可与从 Web 服务返回的数据进行交互。
原文地址:
https://netbeans.org/kb/docs/websvc/client_zh_CN.html

NetBeans 生成代码调用webService调用sopa相关推荐

  1. MATLAB的Curve Fitting Tool 生成代码并被调用

    以MATLAB2014b为例: 打开Curve Fitting:应用程序>>Curve Fitting: 拟合:选择数据源>>X/Y/Z data(没有的话运行下你想曲面拟合的 ...

  2. 关于js实现的Ajax调用,webService,一般处理程序,aspx

    记得以前学的时候,网上的资料一大堆,就是没几个看的懂,都是理论,包括我目前看的mvc书都是一样,废话一堆,其实东西没那么难,让作者把某个技术吹上天了. 下面是一些初学者,比较实用的代码,欢迎大虾指导. ...

  3. java程序如何生成客户端_java webservice生成客户端代码并调用

    wsimport简介 在JDK的bin文件夹中,有一个wsimport.exe工具,可依据wsdl文件生成相应的类文件,将生存在本地这些类文件拷贝到需要使用的项目中,就可以像调用本地的类一样调用web ...

  4. Apache CXF生成java代码用java调用Webservice接口

    这里写自定义目录标题 使用java调用webservice接口 使用java调用webservice接口 当我们使用java去访问webservice的接口时,有很多种方式,这里我们使用apache ...

  5. java使用CXF调用webservice(生成客户端代码方式)

    1:下载CXF     进入apache官网下载:http://cxf.apache.org/download.html        解压到某个路径下例如:C:\Program Files\apac ...

  6. 通过IDE生成和手动call调用webservice

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 通过IDE自动生成的代码调用webservice服务 我们的IDE一般来说都是能够通过各种各样的工具 ...

  7. asmx+java客户端生成_java 调用webservice (asmx) 客户端开发示例

    这是本人第一次写博客,其实就是自己做个笔记,写的很粗糙,也希望能给跟我遇到同样问题的你一点帮助. 因为最近有个项目要调用webservice接口,之前接触的都是Java开发服务端和客户端的接口,开发前 ...

  8. mysql 调用webservice_C#调用Webservice的代码实现方式汇总

    1-添加服务引用: (1)工程 - Service References - 添加服务引用: (2)在"添加服务引用"中输入Webservice网站发布地址,并敲回车或点击&quo ...

  9. ASP.NET定时调用WebService 运行后台代码

    效果: 通过在网站的Global.asax的Application_Start方法中 加入定时器 定时调用WebService 该WebService的一个方法 负责在后台 向数据库的某个表加入数据 ...

最新文章

  1. 来源oa_骨性关节炎(OA)的初期管理——早点行动起来
  2. favicon支持的图片格式
  3. python实现冒泡排序算法的非递归版本_python排序算法速度比较:快速排序,归并排序,冒泡排序...
  4. python基本语法:列表(列表和元组的区别)
  5. java 数组大数乘法_java – 在数组中查找3个数字的最大乘积
  6. java字节输出流方法,Java-IO:File和字节输入输出流
  7. 通讯框架 t-io 学习——给初学者的Demo:ShowCase设计分析
  8. html全屏banner轮播代码,基于jquery实现全屏banner自动轮播切换
  9. 日本用活体肌肉构建机械臂,人类与机器融合取得新突破
  10. android ndk 头文件,笔记:Android源码和NDK目录及头文件
  11. 继承求不同形状图形的周长和面积
  12. 在线文件管理系统 下载地址
  13. 形容词和副词(专升本语法)
  14. 【高数】高数第五章节——定积分积分上限函数牛顿——莱布尼兹公式反常积分与广义积分
  15. 什么是IDOC,以及IDOC的步骤_小七_新浪博客
  16. ts版操作localStorage和sessionStorage工具
  17. 236767服务器网站,南京前三的FIL服务器网站
  18. oracle查询截图,Oracle高级查询
  19. 什么是云存储?它的优势在哪里
  20. 大揭秘!Python处理办公自动化的10大场景!

热门文章

  1. SpringBoot集成Kafka简单应用
  2. 假设电话收费标准为: (1)国际长途1.00元/分钟,(2) 国内长途0.60元/分钟,(3)市话前3分钟0.20元,3分钟以后0.10元/分钟。现假设某话单文件中每条话单包含如下信息:通话日期(10
  3. 时间序列模型之相空间重构
  4. 拉黑技巧/幻隐网络科技
  5. 闪传“一键换机”帮你快速转移手机数据
  6. 易语言防破解防爆暗桩源码
  7. 时尚零售商Shein被曝赴美上市搁浅:创始人许仰天疑改国籍
  8. 阿里云、腾讯云、百度云、华为云哪家的性能最好?
  9. 一文总结旋转目标检测全面综述:论文方法与代码
  10. php 字符串判断维文,学习文史哲 维 文