Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Dúvida no Ex. 5 da Aula 2 - Personalizando o serviço

Estou tentando rodar o código descriminado no exercício e toda vez que rodo o SOAP ele me retorna o erro abaixo:

Estoque rodando: http://localhost:8080/estoquews
Chamando todos os itens: 
fev 11, 2016 10:38:15 AM com.sun.xml.internal.ws.server.sei.TieHandler createResponse
GRAVE: null
java.lang.NullPointerException
    at br.com.caelum.estoque.modelo.ws.EstoqueWS.getItens(EstoqueWS.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.Trampoline.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.xml.internal.ws.api.server.MethodUtil.invoke(Unknown Source)
    at com.sun.xml.internal.ws.api.server.InstanceResolver$1.invoke(Unknown Source)
    at com.sun.xml.internal.ws.server.InvokerTube$2.invoke(Unknown Source)
    at com.sun.xml.internal.ws.server.sei.SEIInvokerTube.processRequest(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source)
    at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.AuthFilter.doFilter(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.ServerImpl$Exchange.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Chamando todos os itens: 
fev 11, 2016 10:40:25 AM com.sun.xml.internal.ws.server.sei.TieHandler createResponse
GRAVE: null
java.lang.NullPointerException
    at br.com.caelum.estoque.modelo.ws.EstoqueWS.getItens(EstoqueWS.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.Trampoline.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.xml.internal.ws.api.server.MethodUtil.invoke(Unknown Source)
    at com.sun.xml.internal.ws.api.server.InstanceResolver$1.invoke(Unknown Source)
    at com.sun.xml.internal.ws.server.InvokerTube$2.invoke(Unknown Source)
    at com.sun.xml.internal.ws.server.sei.SEIInvokerTube.processRequest(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source)
    at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.AuthFilter.doFilter(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.ServerImpl$Exchange.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

PublicaEstoqueWS.java

package br.com.caelum.estoque.modelo.ws;

import javax.xml.ws.Endpoint;

public class PublicaEstoqueWS {
    public static void main(String[] args) {
        String address="http://localhost:8080/estoquews";
        EstoqueWS implementor=new EstoqueWS();

        System.out.println("Estoque rodando: "+address);

        Endpoint.publish(address, implementor);
    }
}

EstoqueWS.java

package br.com.caelum.estoque.modelo.ws;

import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;

import br.com.caelum.estoque.modelo.item.Filtro;
import br.com.caelum.estoque.modelo.item.Filtros;
import br.com.caelum.estoque.modelo.item.Item;
import br.com.caelum.estoque.modelo.item.ItemDao;
import br.com.caelum.estoque.modelo.item.ListaItens;

@WebService
public class EstoqueWS {

    ItemDao dao = new ItemDao();

    @WebMethod(operationName="litarItens")
    @WebResult(name="itens")
    public ListaItens getItens(Filtros filtros){
        System.out.println("Chamando todos os itens: ");
        List<Filtro> lista = filtros.getLista();
        List<Item> itensResultado = dao.todosItens(lista);
        return new ListaItens(itensResultado);
    }
}

Filtros.java

package br.com.caelum.estoque.modelo.item;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Filtros {

    @XmlElement(name="filtro")
    private List<Filtro> filtros;

    public Filtros(List<Filtro> filtros) {
        this.filtros = filtros;
    }

    Filtros() {
    }

    public List<Filtro> getLista() {
        return filtros;
    }

}

ItemDAO.java

package br.com.caelum.estoque.modelo.item;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


public class ItemDao {

    private static Map<String, Item> ITENS = new LinkedHashMap<>();

    public ItemDao() {
        popularItensNoMapa();
    }

    public void cadastrar(Item item) {
        ITENS.put(item.getCodigo(), item);
    }

    public ArrayList<Item> todosItens(List<Filtro> filtros) {

        ArrayList<Item> resultados = new ArrayList<Item>();
        Collection<Item> todosItens = ITENS.values();

        if (filtros == null || filtros.isEmpty()) {
            resultados.addAll(todosItens);
            return resultados;
        }

        for(Filtro filtro : filtros) {
            for (Item item : todosItens) {

                String tipo = filtro.getTipo().getNome();
                String nome = filtro.getNome();

                if(itemPossuiTipo(item, tipo) && itemPossuiNome(item, nome)){
                    resultados.add(item);
                }
            }
        }

        return resultados;
    }

    //este método existe apenas para facilitar o primeiro exercicio que não usa o filtro
    public ArrayList<Item> todosItens() {
        return new ArrayList<>(ITENS.values());
    }

    private boolean itemPossuiNome(Item item, String nome) {
        return item.getNome().contains(nome);
    }

    private boolean itemPossuiTipo(Item item, String tipo) {
        return item.getTipo().equals(tipo);
    }

    public Item quantidadeDo(String codigo) {
        return ITENS.get(codigo);
    }



    private void popularItensNoMapa() {
        ITENS.put("MEA", new Item.Builder().comCodigo("MEA").comNome("MEAN").comTipo("Livro").comQuantidade(5).build());
        ITENS.put("MEA", new Item.Builder().comCodigo("SEO").comNome("SEO na Prática").comTipo("Livro").comQuantidade(4).build());
        ITENS.put("RUB", new Item.Builder().comCodigo("RUB").comNome("Jogos com Ruby").comTipo("Livro").comQuantidade(8).build());
        ITENS.put("GAL", new Item.Builder().comCodigo("GAL").comNome("Galaxy Tab").comTipo("Tablet").comQuantidade(3).build());
        ITENS.put("IP4", new Item.Builder().comCodigo("IP4").comNome("IPhone 4 C").comTipo("Celular").comQuantidade(7).build());
        ITENS.put("IP5", new Item.Builder().comCodigo("IP5").comNome("IPhone 5").comTipo("Celular").comQuantidade(3).build());
        ITENS.put("IP6", new Item.Builder().comCodigo("IP6").comNome("IPhone 6 S").comTipo("Celular").comQuantidade(10).build());
        ITENS.put("MOX", new Item.Builder().comCodigo("MOX").comNome("Moto X").comTipo("Celular").comQuantidade(6).build());
        ITENS.put("MOG", new Item.Builder().comCodigo("MOG").comNome("Moto G").comTipo("Celular").comQuantidade(8).build());
        ITENS.put("MXX", new Item.Builder().comCodigo("MXX").comNome("Moto MAXX").comTipo("Celular").comQuantidade(2).build());
    }



}
7 respostas

Esqueci de colocar o SOAP:

SOAP

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.modelo.estoque.caelum.com.br/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:litarItens/>
            <arg0>
            <!--Optional:-->
            <tipo>Celular</tipo>
            <!--Optional:-->
            <nome>Moto</nome>
         </filtro>
        </arg0>
   </soapenv:Body>
</soapenv:Envelope>

XML

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>java.lang.NullPointerException</faultstring>
      </S:Fault>
   </S:Body>
</S:Envelope>
solução!

Oi Rodrigo,

tenho a impressão que os Filtros não são populados, e por isso vc está recebendo uma NullPointerException na linha:

        List<Filtro> lista = filtros.getLista();

Na mensagem SOAP vc está mandando os filtros?

abs

É isso mesmo. Como na descrição do exercício não fala como passar a mensagem pro SOAP, eu estava passando o filtro errado. Deletei o projeto do SOAP e criei novamente e ele importou as tags corretas ai funcionou.

Obrigado Nico

Oi pessoal,

Eu estou tomando esta mesma exception no SOAP UI:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>java.lang.NullPointerException</faultstring>
      </S:Fault>
   </S:Body>
</S:Envelope>

Não ficou clara pra mim a solução que o Salomão mencionou. Meu Request esta dessa forma:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.estoque.caelum.com.br/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:todosOsItens>
         <!--Optional:-->
         <ws:filtros>
            <!--Zero or more repetitions:-->
            <filtro>
               <!--Optional:-->
               <nome>Celular</nome>
               <!--Optional:-->
               <tipo>Moto</tipo>
            </filtro>
         </ws:filtros>
      </ws:todosOsItens>
   </soapenv:Body>
</soapenv:Envelope>

E minha classe que publica o ws esta dessa forma:

@WebService
public class EstoqueWS {    

    private ItemDao dao = new ItemDao();

    @WebMethod(operationName="todosOsItens")
    @ResponseWrapper(localName="itens")
    @WebResult(name="itens")
    public List<Item> getItens(@WebParam(name="filtros") Filtros filtros){
        System.out.println("Chamando getItens()");

        List<Filtro> listaFiltros = filtros.getLista();

        return dao.todosItens(listaFiltros);
    }
}

Identifiquei aqui que no meu caso o problea estava ocorrendo devido a tag '' do meu Request, alterando essa tag manualmente no Soap UI para '', é feita a busca corretamente.

A tag que mencionei no comentário anterior é:

<ws:filtros>

para conseguir executar sem problemas, preciso alterar manualmente para:

<filtro>
<filtros> ***