端到端二进制 SOAP 附件第 3 部分:对 Web 服务进行编码和测试

在本课中,将学习如何向 Web 服务/会话 Bean 类中添加代码,以将 JPEG 文件转换为字节数组以及将字节数组转换为 java.awt.Image 对象。您还将向公共 Web 服务操作中添加代码以便操作可返回这些 Image 对象。最后,将使用 NetBeans IDE 的 "Test Web Service"(测试 Web 服务)实用程序来在浏览器中对 Web 服务进行测试。

可以从 NetBeans 样例目录中下载 Web 服务的完整样例。

本教程中的课程

此页上的内容适用于 NetBeans IDE 7.2、7.3、7.4 和 8.0
  1. 概述
  2. 创建 Web 服务
  3. => 对 Web 服务进行编码和测试
  4. 修改方案文件和 WSDL 文件以传递二进制数据
  5. 创建 Swing 客户端

本课内容

  1. 对 Web 服务进行编码

    1. 以字节数组形式获取 JPEG 文件
    2. 读取字节数组作为图像
    3. 实现 getFlower
    4. 为所有 JPEG 文件创建字节数组列表
    5. 实现 getThumbnails
  2. 测试 Web 服务

对 Web 服务进行编码

现在得到了包含一组 JPEG 文件和一个 Web 服务的 Web 应用程序。Web 服务被实现为一个无状态会话 Bean。Web 服务包含两个空 Web 操作。在本课中,您将向 Web 服务中添加代码,以将 JPEG 文件转换为字节数组以及将字节数组转换为 java.awt.Image 对象。您还将向公共 Web 服务操作中添加代码以便操作可返回这些 Image 对象。

以字节数组形式获取 JPEG 文件

在此部分,将向 FlowerService 类主体中添加一对私有方法。这些方法采用鲜花的名称,创建到鲜花的 JPEG 文件的路径,并返回 JPEG 文件的二进制表示(字节数组)。在后续部分中,将向公共 Web 服务操作中添加代码以使操作调用这些私有方法。

  1. 打开项目的 "Source"(源)视图。需要添加代码,该代码采用图像的名称,基于该名称创建到图像的路径,以及检索图像以作为字节数组。将以下代码键入或粘贴到 FlowerService 类主体中:
    private byte[] getFlowerBytes(String name) throws IOException {
        URL resource = this.getClass().getResource("/org/flower/resources/"+name+".jpg");
        return getBytes(resource);
    }
  2. 随即出现 IDE 无法找到类 URL 的警告。通过手动方式或者按 Ctrl-Shift-I 组合键(在 Mac 上为 ⌘-Shift-I 组合键)为 java.net.URL 添加一条导入语句。
  3. 随即出现新的警告。警告表明 IDE 无法找到 getBytes 方法。左键单击警告图标然后单击提示以创建 getBytes 方法。
    创建缺少的方法的提示
  4. 编辑器会将焦点置于刚刚创建的 getBytes 方法上。将以下代码添加到方法中。此代码打开到 URL 的连接,通过 getFlowerBytes 方法传递该 URL 并返回一个 InputStream。然后此代码读取输入流(一次 1024 个字节),将字节存储在字节数组缓冲区中,接着再从缓冲区写入 ByteArrayOutputStream
    private byte[] getBytes(URL resource) throws IOException {
        InputStream in = resource.openStream();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        for(int read; (read = in.read(buf)) != -1;) {
            bos.write(buf, 0, read);
        }
        return bos.toByteArray();
    }
  5. java.io.InputStreamjava.io.ByteArrayOutputStream 添加导入语句。

读取字节数组作为图像

在此部分,将向 FlowerService 类主体中添加一个私有方法。该方法传入一个代表 JPEG 文件的字节数组,并返回 java.awt.Image 对象。请注意,字节数组是由 getBytes(URL) 方法所创建的,该方法在以字节数组形式获取 JPEG 文件部分中创建。

  1. FlowerService 类主体中,添加以下名为 getImage 的私有方法。getImage 方法的返回类型为 Image。该方法采用两个参数。第一个参数是由 getBytes 方法创建的字节数组。第二个参数是一个布尔值,用于表示该图像是否为缩略图。getImage 方法抛出一个 IOException
    private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {
        }
  2. getImage 方法主体中,添加一行代码,以通过该方法作为参数传入的字节数组来创建 ByteArrayInputStream
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
  3. 添加一行代码,以通过 ByteArrayInputStream 创建一个 Object
    Object source = bis;
  4. 添加一行代码,以通过通用 Object 创建一个 ImageInputStream
    ImageInputStream iis = ImageIO.createImageInputStream(source);
  5. 添加一行代码来为所有当前注册的可以解码 JPEG 文件的 ImageReader 创建一个 Iterator
    Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
  6. 添加一行代码,用于通过 Iterator 中的下一个元素创建 ImageReader
    ImageReader reader = (ImageReader) readers.next();
  7. 添加代码行以创建默认的图像读取参数,但是如果 Image 代表缩略图,请将四种二次采样中的一种添加到图像读取参数中。
    ImageReadParam param = reader.getDefaultReadParam();
    if (isThumbnail) {
        param.setSourceSubsampling(4, 4, 0, 0);
    }
  8. 最后,添加代码以使用 ImageReader 对象来读取 ImageInputStream 对象,并基于该对象和图像读取参数来返回 Image
    reader.setInput(iis, true);
    return reader.read(0, param);
  9. 按 Ctrl-Shift-I 组合键(在 MacOS 上按 ⌘-Shift-I 组合键)。"Fix All Imports"(修复所有导入)对话框即打开。接受 "Fix All Imports"(修复所有导入)对话框的默认建议,然后单击 "OK"(确定)。
    显示已选定默认 java.util.Iterator 类的 "Fix All Imports"(修复所有导入)对话框

getImage 方法现在已完成。

private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
    Object source = bis; // File or InputStream
    ImageInputStream iis = ImageIO.createImageInputStream(source);
    Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
    ImageReader reader = (ImageReader) readers.next();
    ImageReadParam param = reader.getDefaultReadParam();
    if (isThumbnail) {
        param.setSourceSubsampling(4, 4, 0, 0);
    }
    reader.setInput(iis, true);
    return reader.read(0, param);
}

实现 getFlower

将以下实现代码添加到 getFlower() 方法中以通过花的名称来获取鲜花并返回该花的图像,如下所示。请注意,此代码调用私有的 getFlowerBytes(name) 方法来以字节数组形式获取 JPEG 文件。然后该代码调用私有的 getImage 方法来返回字节数组以作为 Image 对象。

@WebMethod(operationName = "getFlower")
public Image getFlower(@WebParam(name = "name") String name) throws IOException {
    byte[] bytes = getFlowerBytes(name);
    return getImage(bytes, false);
}

为所有 JPEG 文件创建字节数组列表

  1. FlowerService 类主体的顶部,创建一个用于表示每朵花名称的 String 数组。
    private static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};
  2. 添加一个方法,该方法创建一个 ArrayList,并将每朵花的字节数组添加到 List 中。
    private List allFlowers() throws IOException {
        List flowers = new ArrayList();
        for (String flower:FLOWERS) {
            URL resource = this.getClass().getResource("/org/flower/resources/"+flower+".jpg");
            flowers.add(getBytes(resource));
        }
        return flowers;
    }
  3. java.util.ArrayListjava.util.List 添加导入语句。

实现 getThumbnails

按照如下所示更改 getThumbnails() 方法。请注意,添加实现代码并将返回类型从 List 更改为 List<Image>。还请注意,将布尔型 isThumbnail 的值 true 传递到 getImage 方法。getThumbnails 的实现代码调用 allFlowers 方法来为所有 JPEG 文件创建字节数组列表。然后 getThumbnails 方法创建一个 ImageList 并为每朵花调用 getImage 方法,从而将该花的字节数组作为 Image 对象返回,并将该 Image 添加到 List 中。

@WebMethod(operationName = "getThumbnails")
public List<Image> getThumbnails() throws IOException {
    List<byte[]> flowers = allFlowers();
    List<Image> flowerList = new ArrayList<Image>(flowers.size());
    for (byte[] flower : flowers) {
        flowerList.add(getImage(flower, true));
    }
    return flowerList;
}

结合的 Web 服务/会话 Bean 现在已完成。Web 服务类的最终窗体如下:

package org.flower.service;

import java.awt.Image; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.ejb.Stateless; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream;

@WebService(serviceName = "FlowerService") @Stateless() public class FlowerService {

private static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};

@WebMethod(operationName = "getFlower") public Image getFlower(@WebParam(name = "name") String name) throws IOException { byte[] bytes = getFlowerBytes(name); return getImage(bytes, false); }

@WebMethod(operationName = "getThumbnails") public List<Image> getThumbnails() throws IOException { List flowers = allFlowers(); List<Image> flowerList = new ArrayList<Image>(flowers.size()); for (byte[] flower : flowers) { flowerList.add(getImage(flower, true)); } return flowerList; }

private byte[] getFlowerBytes(String name) throws IOException { URL resource = this.getClass().getResource("/org/flower/resources/" + name + ".jpg"); return getBytes(resource); }

private byte[] getBytes(URL resource) throws IOException { InputStream in = resource.openStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; for (int read; (read = in.read(buf)) != -1;) { bos.write(buf, 0, read); } return bos.toByteArray(); }

private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); Iterator readers = ImageIO.getImageReadersByFormatName("jpeg"); ImageReader reader = (ImageReader) readers.next(); Object source = bis; // File or InputStream ImageInputStream iis = ImageIO.createImageInputStream(source); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); if (isThumbnail) { param.setSourceSubsampling(4, 4, 0, 0); } return reader.read(0, param); }

private List allFlowers() throws IOException { List flowers = new ArrayList(); for (String flower : FLOWERS) { URL resource = this.getClass().getResource("/flower/album/resources/" + flower + ".jpg"); flowers.add(getBytes(resource)); } return flowers; } }

测试 Web 服务

既然 Web 服务已完成,您可以对其进行部署和测试。

测试 Web 服务:

  1. 右键单击 "FlowerAlbumService" 节点,然后选择 "Deploy"(部署)。IDE 编译源代码,启动 GlassFish Server,并将项目的 WAR 文件部署到服务器。如果打开 "Services"(服务)窗口,将在服务器的 "Applications"(应用程序)节点中看到已部署的 FlowerService

    重要说明:GlassFish Server Open Source Edition 的版本必须是 3.1 或更高版本。

    "Services"(服务)窗口中的已部署 FlowerService
  2. 展开项目的 "Web Services"(Web 服务)节点。右键单击 "FlowerService" 然后选择 "Test Web Service"(测试 Web 服务)。
    显示 "Test Web Service"(测试 Web 服务)选项的上下文菜单
  3. Web 服务测试器在浏览器中打开。在 getFlower 参数字段中键入 "rose"。
    打开 Web 服务测试器
  4. getFlower 按钮。IDE 在浏览器中显示有关调用的信息。查看“Method Returned”时,会看到乱码。您想要看到一幅图像,而不是一系列的符号。但是,由于 java.awt.Image 不是有效的方案类型,需要手动配置方案文件以返回二进制 image/jpeg 数据。这将在下一个教程中完成。
    浏览器窗口中的 Web 服务测试器的结果
  5. 后续步骤:

    修改方案文件和 WSDL 文件以传递二进制数据


    要发送意见和建议、获得支持以及随时了解 NetBeans IDE Java EE 开发功能的最新开发情况,请加入 邮件列表

get support for the NetBeans

Support


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo