corner imagecorner image
IDEPlatformPluginsDocs & SupportCommunityPartners

Anexo SOAP binário de ponta a ponta parte 3: codificando e testando serviços Web

Nesta lição você adiciona código à classe bean do serviço/sessão Web para converter arquivos JPEG para matrizes de bytes e as matrizes de bytes para objetos java.awt.Image. Você também adiciona código às operações do serviço da Web público para que eles retornem esses objetos Imagem. Por último, você testa o serviço da Web em um navegador utilizando o utilitário de serviços Web de teste do NetBeans IDE.

É possível baixar uma amostra completa do serviço da Web do Catálogo de amostras do NetBeans.

Lições deste tutorial

O conteúdo desta página se aplica ao NetBeans IDE 6.9-7.1
  1. Visão geral
  2. Criando o serviço da Web
  3. => Codificando e testando o serviço da Web
  4. Modificando o esquema e os arquivos WSDL para passar dados binários
  5. Criando o cliente Swing

Conteúdo desta lição

  1. Codificação do serviço da Web

    1. Obtenha um arquivo JPEG como uma matriz de bytes
    2. Leia uma matriz de bytes como uma imagem
    3. Implemente getFlower
    4. Crie uma lista de matrizes de bytes para todos os arquivos JPEG
    5. Implemente getThumbnails
  2. Testando o serviço Web

Codificação do serviço da Web

Agora você tem um aplicativo da Web que contém um conjunto de arquivos JPEG e um serviço da Web. O serviço da Web é implementado como um bean de sessão sem estado. O serviço da Web contém duas operações Web vazias. Nesta lição, o código é adicionado ao serviço da Web para converter arquivos JPEG para matrizes de bytes e as matrizes de bytes para objetos java.awt.Image. Você também adiciona código às operações do serviço da Web público para que eles retornem esses objetos Imagem.

Obter um arquivo JPEG como uma matriz de bytes

Nesta seção, um par de métodos privados é adicionado ao corpo da classe FlowerService . Esses métodos recebem o nome de uma flor, criam o caminho para o arquivo JPEG da flor e retornam uma representação binária do arquivo JPEG (uma matriz de bytes). Em seções posteriores, o código é adicionado às operações de serviço da Web pública para que as operações chamem esses métodos privados.

  1. Abra a visualização Código-fonte do projeto. É necessário adicionar o código que recebe o nome de uma imagem, cria um caminho para a imagem com base nesse nome e recupera a imagem como uma matriz de bytes. Digite ou cole o código a seguir no corpo da classe FlowerService:
    private byte[] getFlowerBytes(String name) throws IOException {
        URL resource = this.getClass().getResource("/org/flower/resources/"+name+".jpg");
        return getBytes(resource);
    }
  2. Um aviso aparece dizendo que o IDE não consegue encontrar o URL da classe. Adicione uma declaração de importação para o java.net.URL manualmente ou pressionando Ctrl-Shift-I (⌘-Shift-I no Mac).
  3. Um novo aviso aparece. O aviso afirma que o IDE não pode encontrar o método getBytes. Clique com o botão esquerdo do mouse no ícone de aviso e clique na dica para criar o método getBytes.
    Dica para criar um método ausente
  4. O editor se concentra no método getBytes que você acabou de criar. Adicione o código a seguir ao método. Esse código abre uma conexão para o URL que você passou do método getFlowerBytes e retorna um InputStream. Em seguida, o código lê o fluxo de entrada 1024 bytes por vez, armazena os bytes em um buffer de matriz de bytes e escreve a partir do buffer em um 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. Adicione instruções importantes para java.io.InputStream e java.io.ByteArrayOutputStream.

Ler uma matriz de bytes como uma imagem

Nesta seção, um método privado é adicionado ao corpo da classe FlowerService . Esse método pega uma matriz de bytes que representa um arquivo JPEG e retorna um objeto java.awt.Image. Observe que a matriz de bytes é criada pelo método getBytes(URL) que você criou na seção Obtenha um arquivo JPEG como uma matriz de bytes.

  1. No corpo da classe FlowerService, adicione o método privado a seguir, chamado getImage. O tipo de retorno do método getImage é Imagem. O método utiliza dois parâmetros. O primeiro parâmetro é uma matriz de bytes criada pelo método getBytes. O segundo parâmetro é um booleano que indica se a imagem é uma miniatura. O método getImage lança uma exceção IOException.
    private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {
        }
  2. No corpo do método getImage, adicione uma linha que cria um ByteArrayInputStream da matriz de bytes que o método utiliza como parâmetro.
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
  3. Adicione uma linha que cria um Objeto do ByteArrayInputStream.
    Object source = bis;
  4. Adicione uma linha que cria uma ImageInputStream do Objeto genérico.
    ImageInputStream iis = ImageIO.createImageInputStream(source);
  5. Adicione uma linha que cria um Iterador de todos os ImageReader atualmente registrados que podem decodificar arquivos JPEG.
    Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
  6. Adicione uma linha que cria um ImageReader do próximo elemento do Iterador.
    ImageReader reader = (ImageReader) readers.next();
  7. Adicione linhas que criam parâmetros de leitura de imagem padrão mas adicione 1 em 4 subamostragem aos parâmetros de leitura da imagem se a Imagem representa uma miniatura.
    ImageReadParam param = reader.getDefaultReadParam();
    if (isThumbnail) {
        param.setSourceSubsampling(4, 4, 0, 0);
    }
  8. Por último, adicione o código que utiliza o objeto ImageReader para ler o objeto ImageInputStream e retornar uma Imagem, com base nesse objeto e nos parâmetros de leitura da imagem.
    reader.setInput(iis, true);
    return reader.read(0, param);
  9. Pressione Ctrl-Shift-I (⌘-Shift-I no MacOS). A caixa de diálogo Corrigir todas as importações é aberta. Aceite as sugestões padrão da caixa de diálogo Corrigir todas as importações e clique em OK.
    Caixa de diálogo Corrigir todas as importações mostrando a classe java.util.Iterator selecionada

O método getImage agora está concluído.

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);
}

Implementar o getFlower

Adicione o código de implementação a seguir ao método getFlower() para obter uma flor pelo seu nome e retornar a imagem dessa flor, como se segue. Observe que esse código chama o método getFlowerBytes(name) para obter o arquivo JPEG como uma matriz de bytes. Em seguida, o código chama o método getImage privado para retornar a matriz de bytes como um objeto Imagem.

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

Crie uma lista de matrizes de bytes para todos os arquivos JPEG

  1. Na parte superior do corpo da classe de FlowerService, crie uma matriz de strings dos nomes de cada flor.
    private static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};
  2. Adicione um método que cria uma ArrayList e adiciona uma matriz de bytes para cada flor à Lista.
    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. Adicione instruções de importação para java.util.ArrayList e java.util.List.

Implemente getThumbnails

Altere o método getThumbnails() como se segue. Observe que você adiciona o código de implementação e altera o tipo de retorno de Lista para Lista<Imagem>. Observe também que você passa o valor booleano de isThumbnail como verdadeiro para o método getImage. O código de implementação de getThumbnails chama o método allFlowers para criar uma lista de matrizes de bytes para todos os arquivos JPEG. O método getThumbnails cria, em seguida, uma Lista de Imagens e chama o método getImage para cada flor, para retornar a matriz de bytes para essa flor como um objeto Image e adiciona essa Imagem à Lista.

@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;
}

O bean de sessão/serviço combinado agora está completo. Segue o formulário final da classe do serviço da Web:

pacote 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() @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; } }

Testando o serviço Web

Agora que o serviço da Web está completo, é possível implantá-lo e testá-lo.

Para testar o serviço Web:

  1. Clique com o botão direito do mouse no nó FlowerAlbumService, e selecione Implantar. O IDE compila o código-fonte, inicia o GlassFish Server Open Source Edition e implanta o arquivo WAR do projeto no servidor. Se você abrir a janela Serviços, poderá ver o FlowerService implantado no nó Aplicativos do servidor.

    Importante: o GlassFish Server Open Source Edition deve ser versão 3.1 b27 ou posterior. O arquivo de esquema personalizado que você cria em Modificando os arquivos de esquema e WSDL não funciona em versões anteriores do servidor do GlassFish. Verifique a versão de seu servidor GlassFish na janela Serviços.

    FlowerService implantando na janela Serviços
  2. Expanda o nó Serviços da Web do projeto. Clique com o botão direito do mouse em FlowerService e selecione Testar serviço da Web.
    Menu de contexto mostrando a opção Testar serviço da Web
  3. O testador do serviço da Web é aberto no navegador. Digite "rosa" no campo do parâmetro de getFlower.
    Abra o testador do serviço da Web
  4. Pressione o botão getFlower. O IDE mostra informações sobre o chamado no navegador. Ao observar o "Método retornado", você vê que ele está truncado. Você deseja ver uma imagem, não uma série de símbolos. Entretanto, já que java.awt.Image não é um tipo de esquema válido, você precisa configurar manualmente o arquivo do esquema para retornar dados image/jpeg binários. Você fará isso no próximo tutorial.
    Resultados do testador do serviço da Web na janela do navegador
  5. Próxima etapa:

    Modificando o esquema e os arquivos WSDL para passar dados binários


    Para enviar comentários e sugestões, obter suporte e se manter informado sobre os mais recentes desenvolvimentos dos recursos de desenvolvimento de Java EE do NetBeans IDE, inscreva-se na lista de notícias .