2
respostas

Aula 2 - Erro ao usar FIltros

Estou tentando utilizar os filtros, mas estou recebendo NullPointerException.

Utilizei a pesquisa das seguintes formas, todas retornaram da mesma forma:

<nome>MEAN</nome> <nome>?</nome> <nome></nome>

Ele apresenta erro na lista35 do ItemDAO (classe que não mexemos), dentro do método todosItens: String tipo = filtro.getTipo().getNome();

no SOAP está assim:

   <soapenv:Header/>
   <soapenv:Body>
      <ws:TodosOsItens>
         <!--Optional:-->
         <filtros>                          
            <!--Zero or more repetitions:-->
            <filtro>
               <!--Optional:-->
               <nome></nome>
               <!--Optional:-->
               <tipo></tipo>
            </filtro>
         </filtros>
      </ws:TodosOsItens>
   </soapenv:Body>
</soapenv:Envelope>

Classe Filtros

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

}

Classe EstoqueWS

public class EstoqueWS {

    private ItemDao dao = new ItemDao();

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

Mensagem de Erro

fev 18, 2020 11:37:54 AM com.sun.xml.internal.ws.server.sei.TieHandler createResponse
GRAVE: null
java.lang.NullPointerException
    at br.com.caelum.estoque.modelo.item.ItemDao.todosItens(ItemDao.java:35)
    at br.com.caelum.estoque.ws.EstoqueWS.getItens(EstoqueWS.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.xml.internal.ws.api.server.MethodUtil.invoke(MethodUtil.java:68)
    at com.sun.xml.internal.ws.api.server.InstanceResolver$1.invoke(InstanceResolver.java:235)
    at com.sun.xml.internal.ws.server.InvokerTube$2.invoke(InvokerTube.java:134)
    at com.sun.xml.internal.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:73)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862)
    at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:404)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:706)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:260)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:98)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:82)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
    at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
    at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Podem me ajudar, por favor?

2 respostas

[CONTINUANDO...]

Se eu usar o filtro do tipo, funciona:

<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:-->
         <filtros>
            <!--Zero or more repetitions:-->
            <filtro>
               <!--Optional:-->
               <nome></nome>
               <!--Optional:-->
               <tipo>Livro</tipo>
            </filtro>
         </filtros>
      </ws:todosOsItens>
   </soapenv:Body>
</soapenv:Envelope>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns2:todosOsItensResponse xmlns:ns2="http://ws.estoque.caelum.com.br/">
         <item>
            <item>
               <codigo>SEO</codigo>
               <nome>SEO na Prática</nome>
               <quantidade>4</quantidade>
               <tipo>Livro</tipo>
            </item>
            <item>
               <codigo>RUB</codigo>
               <nome>Jogos com Ruby</nome>
               <quantidade>8</quantidade>
               <tipo>Livro</tipo>
            </item>
         </item>
      </ns2:todosOsItensResponse>
   </S:Body>
</S:Envelope>

Se usar tipo e nome, também funciona, mas se usar só nome, não funciona...

<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:-->
         <filtros>
            <!--Zero or more repetitions:-->
            <filtro>
               <!--Optional:-->
               <nome>Jogos com Ruby</nome>
               <!--Optional:-->
               <tipo></tipo>
            </filtro>
         </filtros>
      </ws:todosOsItens>
   </soapenv:Body>
</soapenv:Envelope>

Retorno:

<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>

Olá Rafael, como vai? Tudo certo?

Esse NullPointerException indica que está ocorrendo um problema de referência nula ao chamar o método getNome() em filtro.getTipo().getNome().

Com base no código que você mandou parece que o problema está relacionado à forma como você está configurando o filtro no SOAP. Quando você envia apenas o elemento no filtro e deixa o elemento vazio, está causando o erro. Isso ocorre porque, ao chamar filtro.getTipo().getNome(), você está tentando acessar o método getNome() em um objeto nulo.

Você pode tentar verificar se o filtro possui um tipo antes de chamar o método getNome(). Uma maneira de fazer isso é adicionar uma condição if na classe ItemDao antes de acessar o tipo do filtro, conforme mostrado abaixo:

public List<Item> todosItens(List<Filtro> filtros) {
    // ...
    for (Filtro filtro : filtros) {
        if (filtro.getTipo() != null) {
            String tipo = filtro.getTipo().getNome();
            // Restante do código
        }
    }
    // ...
}

Espero ter ajudado e bons estudos!