// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= JAX-WS Web 服务入门指南
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: JAX-WS Web 服务入门指南 - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, JAX-WS Web 服务入门指南

link:http://www.jcp.org/en/jsr/detail?id=224[+Java API for XML Web Services (JAX-WS), JSR 224+] 是 Java EE 平台的一个重要组成部分。作为 Java API for XML-based RPC 1.1 (JAX-RPC) 发行版的后续版本，JAX-WS 简化了使用 Java 技术开发 Web 服务的任务。它通过为多种协议（如 SOAP 1.1、SOAP 1.2、XML）提供支持，以及提供用于支持其他协议和 HTTP 的工具，解决了 JAX-RPC 1.1 中存在的一些问题。JAX-WS 使用 JAXB 2.0 执行数据绑定，并支持定制由控件生成的服务端点接口。JAX-WS 利用其对标注的支持，简化了 Web 服务开发，并减小了运行时 JAR 文件的大小。

本文档介绍了使用 IDE 开发 JAX-WS Web 服务的基础知识。创建 Web 服务后，您将编写三个不同的 Web 服务客户端，这些客户端通过网络使用 Web 服务（称为“使用”Web 服务）。这三个客户端分别是 Java SE 应用程序中的 Java 类、Web 应用程序中的 Servlet 和 Web 应用程序中的 JSP 页。link:./client.html[+开发 JAX-WS Web 服务客户端+]是集中讨论客户端的更高级教程。


image::images/netbeans-stamp-80-74-73.png[title="此页上的内容适用于 NetBeans IDE 7.2、7.3、7.4 和 8.0"]

* 在以下客户端中使用 Web 服务

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

|===
|软件或资源 |要求的版本 

|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |Java EE 下载包 

|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Java 开发工具包 (JDK)+] |JDK 7 或 JDK 8
 

|符合 Java EE 规范的 Web 服务器或应用服务器 |GlassFish Server Open Source Edition 
Oracle WebLogic Server 
|===

*注：*GlassFish Server 可以随同 NetBeans IDE 的 Java EE 发行版本一起安装。此外，也可以访问 link:https://glassfish.java.net/download.html[+GlassFish Server 下载页+]或 link:http://tomcat.apache.org/download-60.cgi[+Apache Tomcat 下载页+]。

*重要说明：*Java EE 项目需要使用 GlassFish Server 或 Oracle WebLogic Server 12c。

捆绑的 Tomcat Web 服务器不是 Java EE 完全兼容的 Web 服务器。但是，Tomcat 7.x Web 服务器可以配置为支持一些 Java EE 功能。有关如何将对 Java EE 的支持添加到 Tomcat 中的信息，请参见 link:http://openejb.apache.org/[+Apache TomEE 项目+]。


==   创建 Web 服务

本练习旨在创建一个适用于确定要使用的部署容器的项目。具有项目后，您将在其中创建一个 Web 服务。


=== 选择容器

您可以在 Web 容器或 EJB 容器中部署 Web 服务。这取决于您的具体选择。如果要创建 Java EE 应用程序，则在任何情况下都使用 Web 容器，因为您可以将 EJB 直接放入 Web 应用程序中。例如，如果您计划部署到只有一个 Web 容器的 Tomcat Web Server，请创建一个 Web 应用程序，而不是 EJB 模块。

1. 选择 "File"（文件）> "New Project"（新建项目）（在 Linux 和 Windows 上为 Ctrl-Shift-N 组合键，在 MacOS 上为 ⌘-Shift-N 组合键）。从 "Java Web" 类别中选择 "Web Application"（Web 应用程序），或从 "Java EE" 类别中选择 "EJB Module"（EJB 模块）。

您可以在 Maven 项目中创建 JAX-WS Web 服务。选择 "File"（文件）> "New Project"（新建项目）（在 Linux 和 Windows 上为 Ctrl-Shift-N 组合键，在 MacOS 上为 ⌘-Shift-N 组合键），然后从 "Maven" 类别中选择 "Maven Web Application"（Maven Web 应用程序）或 "Maven EJB module"（Maven EJB 模块）。如果您以前没有同时使用过 Maven 和 NetBeans，请参见 link:http://wiki.netbeans.org/MavenBestPractices[+Maven 最佳做法+]。


[start=2]
. 将该项目命名为  ``CalculatorWSApplication`` 。为该项目选择一个位置。单击 "Next"（下一步）。

[start=3]
. 选择服务器和 Java EE 版本，然后单击 "Finish"（完成）。

要使用 Oracle WebLogic Server，请link:../web/jsf-jpa-weblogic.html#01[+在 IDE 中注册服务器+]。另外，如果使用的是 WebLogic Server，请观看link:../javaee/weblogic-javaee-m1-screencast.html[+将 Web 应用程序部署到 Oracle WebLogic+] 截屏视频。


=== 通过 Java 类创建 Web 服务

1. 右键单击  ``CalculatorWSApplication``  节点，然后选择 "New"（新建）> "Web Service"（Web 服务）。
2. 将 Web 服务命名为  ``CalculatorWS`` ，并在 "Package"（包）中键入  ``org.me.calculator`` 。将 "Create Web Service from Scratch"（从头开始创建 Web 服务）保持选中状态。
3. 如果要在 GlassFish 或 WebLogic 上创建 Java EE 项目，请选择 "Implement Web Service as a Stateless Session Bean"（将 Web 服务作为无状态会话 Bean 实现）。
image::images/generate-ws-ee6.png[]

[start=4]
. 单击 "Finish"（完成）。"Projects"（项目）窗口将显示新 Web 服务的结构，并在编辑器区域中显示源代码。


==   向 Web 服务中添加操作

本练习旨在向 Web 服务中添加一项操作，该操作用于添加从客户端接收到的两个数字。NetBeans IDE 提供了一个对话框，用于将操作添加到 Web 服务中。您可以在 Web 服务可视设计器或 Web 服务上下文菜单中打开该对话框。

*警告：*无法在 Maven 项目中使用该可视设计器。

*将操作添加到 Web 服务中：*

1. 可以：
* 切换到编辑器的 "Design"（设计）视图。 
image::images/design-view.png[]

或：

* 在 "Projects"（项目）窗口中查找 Web 服务的节点。右键单击该节点。此时将打开一个上下文菜单。
image::images/add-op-cx-menu-item.png[]

[start=2]
. 在可视设计器或上下文菜单中，单击 "Add Operation"（添加操作）。"Add Operation"（添加操作）对话框打开。

[start=3]
. 在 "Add Operation"（添加操作）对话框的上半部分中，在 "Name"（名称）中键入  ``add`` ，并在 "Return Type"（返回类型）下拉列表中键入  ``int`` 。

[start=4]
. 在 "Add Operation"（添加操作）对话框的下半部分中，单击 "Add"（添加）以创建  ``int``  类型的参数  ``i`` 。

[start=5]
. 然后，再次单击 "Add"（添加）以创建  ``int``  类型的参数  ``j`` 。

现在，您将看到以下内容：


image::images/jaxws-60-add-operation.png[]

[start=6]
. 在 "Add Operation"（添加操作）对话框的底部，单击 "OK"（确定）。您将返回到编辑器中。

[start=7]
. 删除默认的  ``hello``  操作，方法是在源代码中删除  ``hello()``  方法或在可视设计器中选择  ``hello``  操作并单击 "Remove Operation"（删除操作）。

现在，可视设计器将显示以下内容：


image::images/design-view-with-op.png[title="显示已添加操作的 Web 服务可视设计器"]

[start=8]
. 单击 "Source"（源），然后查看在以上步骤中生成的代码。该代码会因您是否将服务创建为 Java EE 无状态 Bean 而有所不同。您能看到以下屏幕快照中的差别吗？（未作为无状态 Bean 实现的 Java EE 6 或 Java EE 7 服务类似于 Java EE 5 服务。）
image::images/jaxws-60-source.png[] image::images/stateless-ejb-code1.png[]

*注：*在 NetBeans IDE 7.3 和 7.4 中，您可以注意到生成的  ``@WebService``  表示服务名显式指定：
 ``@WebService(serviceName = "CalculatorWS")`` 。


[start=9]
. 在编辑器中，将框架  ``add``  操作扩展为以下代码（所做的更改以粗体显示）：

[source,java]
----

    @WebMethod
    public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
        *int k = i + j;*
        return *k*;
      }
----

正如您在上面的代码中所看到的一样，Web 服务仅接收两个数字，然后返回二者之和。在下一部分中，您将使用 IDE 测试 Web 服务。


== 部署和测试 Web 服务

在将 Web 服务部署到服务器后，如果服务器具有测试客户端，则可以使用 IDE 打开服务器的测试客户端。GlassFish 和 WebLogic Server 提供了测试客户端。

如果您使用的是 Tomcat Web 服务器，则没有测试客户端。您只能运行项目并查看 Tomcat Web 服务页是否打开。此时，在运行项目之前，您需要将 Web 服务作为您的应用程序的入口点。要使 Web 服务成为应用程序的入口点，请右键单击 "CalculatorWSApplication" 项目节点，然后选择 "Properties"（属性）。打开 "Run"（运行）属性，然后在 "Relative URL"（相对 URL）字段中键入  ``/CalculatorWS`` 。单击 "OK"（确定）。要运行项目，请再次右键单击项目节点，然后选择 "Run"（运行）。

*测试是否成功部署到 GlassFish 或 WebLogic Server：*

1. 右键单击该项目，然后选择 "Deploy"（部署）。IDE 将启动应用服务器，构建应用程序，然后将应用程序部署到服务器。可以在 "Output"（输出）视图中的 "CalculatorWSApplication (run-deploy)" 以及 "GlassFish" 服务器或 "Tomcat" 标签中看到这些操作的进度。
2. 在 IDE 的 "Projects"（项目）标签中，展开 CalculatorWSApplication 项目的 "Web Services"（Web 服务）节点。右键单击 "CalculatorWS" 节点，然后选择 "Test Web Service"（测试 Web 服务）。 
image::images/jax-ws-testws.png[]

IDE 在浏览器中打开测试器页（如果您已将 Web 应用程序部署到 GlassFish Server 中）。对于 Tomcat Web Server 和 EJB 模块的部署，情况有所不同：

* 如果已部署到 GlassFish Server，请在测试器页中键入两个数字，如下所示： 
image::images/jax-ws-tester.png[]

将显示这两个数字之和：


image::images/jax-ws-tester2.png[]


== [[样例]] 

您可以选择 "File"（文件）> "New Project"（新建项目）（在 Linux 和 Windows 上为 Ctrl-Shift-N 组合键，在 MacOS 上为 ⌘-Shift-N 组合键），然后导航至 "Samples"（样例）> "Web Services"（Web 服务）> "Calculator (EE6)"（计算器 (EE6)），以打开计算器服务的完整 Java EE 无状态 Bean 版本。

将在 "Samples"（样例）> "Maven" 中提供 Maven 计算器服务和 Maven 计算器客户端。


== 使用 Web 服务

现在，您已经部署了 Web 服务，接下来需要创建一个客户端，以便使用 Web 服务的  ``add``  方法。在这里，您将创建三个客户端：Java SE 应用程序中的 Java 类、Web 应用程序中的 Servlet 和 Web 应用程序中的 JSP 页。

*注：*link:../../../kb/docs/websvc/client.html[+开发 JAX-WS Web 服务客户端+]是集中讨论客户端的更高级教程。


=== 客户端 1：Java SE 应用程序中的 Java 类

在此部分，您将创建一个标准的 Java 应用程序。用于创建应用程序的向导也可以创建 Java 类。之后，您将使用 IDE 的工具来创建一个客户端，并使用在本教程开始时创建的 Web 服务。

1. 选择 "File"（文件）> "New Project"（新建项目）（在 Linux 和 Windows 上为 Ctrl-Shift-N 组合键，在 MacOS 上为 ⌘-Shift-N 组合键）。选择 "Java" 类别中的 "Java Application"（Java 应用程序）选项。将该项目命名为  ``CalculatorWS_Client_Application`` 。将 "Create Main Class"（创建主类）保留为选中状态，并接受所有其他默认设置。单击 "Finish"（完成）。
2. 右键单击  ``CalculatorWS_Client_Application``  节点，然后选择 "New"（新建）> "Web Service Client"（Web 服务客户端）。此时将打开新建 Web 服务客户端向导。
3. 选择 "Project"（项目）作为 WSDL 源。单击 "Browse"（浏览）。浏览至 CalculatorWSApplication 项目中的 CalculatorWS Web 服务。选定 Web 服务后，单击 "OK"（确定）。
image::images/browse-ws.png[]

[start=4]
. 请勿选择包名。将此字段保留为空。
image::images/javaclient-pkg.png[]

[start=5]
. 将其他设置保留为默认值，然后单击 "Finish"（完成）。

"Projects"（项目）窗口将显示新的 Web 服务客户端，其中包括已创建的  ``add``  方法的节点：


image::images/ws-ref-in-client-project.png[]

[start=6]
. 双击以在源代码编辑器中打开主类。将  ``add``  节点拖至  ``main()``  方法下面。
image::images/dnd-add.png[]

现在，您将看到以下内容：


[source,java]
----

public static void main(String[] args) {
    // TODO code application logic here
}
private static int add(int i, int j) {
    org.me.calculator.CalculatorWS_Service service = new org.me.calculator.CalculatorWS_Service();
    org.me.calculator.CalculatorWS port = service.getCalculatorWSPort();
    return port.add(i, j);
}
----

*注：*或者，您也可以在编辑器中单击鼠标右键，然后选择 "Insert Code"（插入代码）> "Call Web Service Operation"（调用 Web 服务操作），而无需拖动  ``add``  节点。


[start=7]
. 在  ``main()``  方法主体中，将 TODO 注释替换为执行以下操作的代码：初始化  ``i``  和  ``j``  的值，调用  ``add()`` ，然后输出结果。

[source,java]
----

public static void main(String[] args) {int i = 3;int j = 4;int result = add(i, j);System.out.println("Result = " + result);
}
----

[start=8]
. 将  ``main()``  方法代码包含在输出异常错误的 try/catch 块中。

[source,java]
----

public static void main(String[] args) {try {int i = 3;int j = 4;int result = add(i, j);System.out.println("Result = " + result);} catch (Exception ex) {System.out.println("Exception: " + ex);}
}
----

[start=9]
. 右键单击项目节点，然后选择 "Run"（运行）。

"Output"（输出）窗口将立即显示二者之和：


[source,java]
----

    compile:
    run:
    Result = 7
      BUILD SUCCESSFUL (total time: 1 second)
----


=== 客户端 2：Web 应用程序中的 Servlet

在此部分，您将创建一个新的 Web 应用程序，随后创建一个 Servlet。然后，借助该 Servlet 使用在本教程开始时创建的 Web 服务。

1. 选择 "File"（文件）> "New Project"（新建项目）（在 Linux 和 Windows 上为 Ctrl-Shift-N 组合键，在 MacOS 上为 ⌘-Shift-N 组合键）。从 "Java Web" 类别中选择 "Web Application"（Web 应用程序）。将该项目命名为  ``CalculatorWSServletClient`` 。单击 "Next"（下一步），然后单击 "Finish"（完成）。
2. 右键单击  ``CalculatorWSServletClient``  节点，然后选择 "New"（新建）> "Web Service Client"（Web 服务客户端）。

此时将打开新建 Web 服务客户端向导。


[start=3]
. 选择 "Project"（项目）作为 WSDL 源，然后单击 "Browse"（浏览）以打开 "Browse Web Services"（浏览 Web 服务）对话框。

[start=4]
. 在 "CalculatorWSApplication" 项目中选择 "CalculatorWS" Web 服务。单击 "OK"（确定）关闭 "Browse Web Services"（浏览 Web 服务）对话框。
image::images/browse-ws.png[]

[start=5]
. 在新建 Web 服务客户端向导中确认包名为空，并保留其他设置的默认值。单击 "Finish"（完成）。

"Projects"（项目）窗口中的 "Web Service References"（Web 服务引用）节点将显示新建客户端的结构，其中包括在本教程前面部分创建的  ``add``  操作。


[start=6]
. 右键单击  ``CalculatorWSServletClient``  项目节点，然后选择 "New"（新建）> "Servlet"。将该 Servlet 命名为  ``ClientServlet`` ，并将其置于名为  ``org.me.calculator.client``  的包中。单击 "Finish"（完成）。

[start=7]
. 要使 servlet 成为应用程序的入口点，请右键单击 "CalculatorWSServletClient" 项目节点，然后选择 "Properties"（属性）。打开 "Run"（运行）属性，然后在 "Relative URL"（相对 URL）字段中键入  ``/ClientServlet`` 。单击 "OK"（确定）。

[start=8]
. 如果  ``ClientServlet.java``  存在错误图标，请右键单击项目节点，然后选择 "Clean and Build"（清理并构建）。

[start=9]
. 在  ``processRequest()``  方法中，在此行后添加一些空行：

[source,xml]
----

    out.println("<h1>Servlet ClientServlet at " + request.getContextPath () + "</h1>");
----

[start=10]
. 在源代码编辑器中，将  ``add``  操作拖至  ``ClientServlet``  类主体中的任意位置。将在类代码的末尾显示  ``add()``  方法。

*注：*或者，您也可以在编辑器中单击鼠标右键，然后选择 "Insert Code"（插入代码）> "Call Web Service Operation"（调用 Web 服务操作），而无需拖动  ``add``  节点。


[source,java]
----

private int add(int i, int j) {org.me.calculator.CalculatorWS port = service.getCalculatorWSPort();return port.add(i, j);
}
----

[start=11]
. 添加执行以下操作的代码：初始化  ``i``  和  ``j``  值，调用  ``add()`` ，然后输出结果。添加的代码以*粗体显示*：

[source,xml]
----

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Servlet ClientServlet</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Servlet ClientServlet at " + request.getContextPath () + "</h1>");

    *    int i = 3;
int j = 4;
int result = add(i, j);
out.println("Result = " + result);*

        out.println("</body>");
        out.println("</html>");
        
    } finally {            out.close();}}
----

[start=12]
. 将添加的代码包含在输出异常错误的 try/catch 块中。

[source,xml]
----

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Servlet ClientServlet</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Servlet ClientServlet at " + request.getContextPath () + "</h1>");
        *try {*
            int i = 3;int j = 4;int result = add(i, j);out.println("Result = " + result);
        *} catch (Exception ex) {
            out.println("Exception: " + ex);
        }*
        out.println("</body>");
        out.println("</html>");
        
    } finally {            out.close();}}
----

[start=13]
. 右键单击项目节点，然后选择 "Run"（运行）。

将启动服务器；同时，系统将构建并部署应用程序，并且打开浏览器以显示计算结果，如下所示： 
image::images/jaxws-60-webclient.png[]


=== 客户端 3：Web 应用程序中的 JSP 页

在此部分中，您将创建一个新的 Web 应用程序，然后在 Web 应用程序向导创建的默认 JSP 页中使用 Web 服务。

*注：*如果要在 Oracle WebLogic 上运行 JSP Web 应用程序客户端，请参见link:../web/jsf-jpa-weblogic.html[+在 WebLogic 上运行 Java Server Faces 2.0 应用程序+]。

1. 选择 "File"（文件）> "New Project"（新建项目）（在 Linux 和 Windows 上为 Ctrl-Shift-N 组合键，在 MacOS 上为 ⌘-Shift-N 组合键）。从 "Java Web" 类别中选择 "Web Application"（Web 应用程序）。将该项目命名为  ``CalculatorWSJSPClient`` 。单击 "Next"（下一步），然后单击 "Finish"（完成）。
2. 在项目节点下展开 "Web Pages"（Web 页）节点并删除  ``index.html`` 。
3. 右键单击  ``Web Pages`` （Web 页）节点，然后在弹出式菜单中选择 "New"（新建）> "JSP"。

如果 JSP 在弹出式菜单中不可用，请选择 "New"（新建）> "Other"（其他），然后在新建文件向导的 "Web" 类别中选择 "JSP"。


[start=4]
. 在新建文件向导中，键入 *index* 作为 JSP 文件的名称。单击 "Finish"（完成）。

[start=5]
. 右键单击  ``CalculatorWSJSPClient``  节点，然后选择 "New"（新建）> "Web Service Client"（Web 服务客户端）。

[start=6]
. 选择 "Project"（项目）作为 WSDL 源。单击 "Browse"（浏览）。浏览至 CalculatorWSApplication 项目中的 CalculatorWS Web 服务。选定 Web 服务后，单击 "OK"（确定）。
image::images/browse-ws.png[]

[start=7]
. 请勿选择包名。将此字段保留为空。

[start=8]
. 将其他设置保留为默认值，然后单击 "Finish"（完成）。

"Projects"（项目）窗口将显示新的 Web 服务客户端，如下所示：

image::images/ws-ref-in-jsp-client.png[]

[start=9]
. 在 "Web Service References"（Web 服务引用）节点中，展开表示 Web 服务的节点。此时将显示您要从客户端调用的  ``add``  操作。

[start=10]
. 将  ``add``  操作拖至客户端的  ``index.jsp``  页，并将其放在 H1 标记下。在  ``index.jsp``  页中立即生成用于调用服务操作的代码，如下所示：

[source,java]
----

<%
try {
    org.me.calculator.CalculatorWSService service = new org.me.calculator.CalculatorWSService();
    org.me.calculator.CalculatorWS port = service.getCalculatorWSPort();
     // TODO initialize WS operation arguments here
    int i = 0;
    int j = 0;
    // TODO process result here
    int result = port.add(i, j);
    out.println("Result = "+result);
} catch (Exception ex) {
    // TODO handle custom exceptions here
}
%>
----

将  ``i``  和  ``j``  的值从 0 更改为其他整数，如 3 和 4。将 catch 块中注释掉的 TODO 行替换为  ``out.println("exception" + ex);`` 。


[start=11]
. 右键单击项目节点，然后选择 "Run"（运行）。

将启动服务器（如果它尚未运行）。同时，系统将构建并部署应用程序，并且打开浏览器以显示计算结果：

image::images/jax-ws-project-jsp-result.png[]


link:/about/contact_form.html?to=3&subject=Feedback:%20JAX-WS%20Services%20in%20NetBeans%20IDE[+发送有关此教程的反馈意见+]



== 另请参见

有关使用 NetBeans IDE 开发 Java EE 应用程序的更多信息，请参见以下资源：

* link:./client.html[+开发 JAX-WS Web 服务客户端+]
* link:./rest.html[+REST 风格的 Web 服务入门指南+]
* link:./wsit.html[+Advanced Web Service Interoperability+]（高级 Web 服务互操作性）
* link:../../../kb/trails/web.html[+Web 服务学习资源+]

要发送意见和建议、获得支持以及随时了解 NetBeans IDE Java EE 开发功能的最新开发情况，请link:../../../community/lists/top.html[+加入 nbj2ee@netbeans.org 邮件列表+]。

