9
respostas

Método getItens retornando null no parâmetro filtros

Bom dia,

Quando vou fazer o teste no SoapUI, ocorre o erro de NullPointer. O parâmetro filtros está vindo null. Não entendi o porque.

@WebMethod(operationName="todosOsItens") @WebResult(name="itens") public ListaItens getItens(@WebParam(name="filtros") Filtros filtros) {

    System.out.println("Chamando todosItens()");

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

   List<Item> todosItens = dao.todosItens(listaFiltros);
   return new ListaItens(todosItens);
}
9 respostas

Você poderia postar aqui o código que você enviou pelo Soap UI?

E também o código do WSDL?

Assim vai ficar mais fácil de entender o que pode ter acontecido.

Olá

Estou com o mesmo problema.

A minha classe EstoqueWS está assim:

@WebService
public class EstoqueWS {

    private ItemDao dao = new ItemDao();

    @WebMethod(operationName = "todosOsItens")
    @WebResult(name = "itens")
    public ListaItens getItens(Filtros filtros) {

        System.out.println("Chamando metodo todosItens()");

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

        List<Item> itensResultado = dao.todosItens(lista);

        return new ListaItens(itensResultado);
    }

}

Filtros:

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

}

Código que foi gerado pelo SoapUI e utilizado para teste:

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

E o wsdl

<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws.estoque.caelum.com.br/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.estoque.caelum.com.br/" name="EstoqueWSService">
<types>
<xsd:schema>
<xsd:import namespace="http://ws.estoque.caelum.com.br/" schemaLocation="http://localhost:8080/estoquews?xsd=1"/>
</xsd:schema>
</types>
<message name="todosOsItens">
<part name="parameters" element="tns:todosOsItens"/>
</message>
<message name="todosOsItensResponse">
<part name="parameters" element="tns:todosOsItensResponse"/>
</message>
<portType name="EstoqueWS">
<operation name="todosOsItens">
<input wsam:Action="http://ws.estoque.caelum.com.br/EstoqueWS/todosOsItensRequest" message="tns:todosOsItens"/>
<output wsam:Action="http://ws.estoque.caelum.com.br/EstoqueWS/todosOsItensResponse" message="tns:todosOsItensResponse"/>
</operation>
</portType>
<binding name="EstoqueWSPortBinding" type="tns:EstoqueWS">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="todosOsItens">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="EstoqueWSService">
<port name="EstoqueWSPort" binding="tns:EstoqueWSPortBinding">
<soap:address location="http://localhost:8080/estoquews"/>
</port>
</service>
</definitions>

Oi Luiz,

Acho que no seu método faltou colocar o @WebParam:

public ListaItens getItens(@WebParam(name = "filtros") Filtros filtros) {
...
}

Veja se esse era o problema.

Oi Rodrigo,

Obrigado pela resposta, mudei a classe e ainda não funcionou.

@WebService
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 metodo todosItens()");
        List<Filtro> lista = filtros.getLista();
        List<Item> itensResultado = dao.todosItens(lista);
        return new ListaItens(itensResultado);
    }

}

Tentei com os dois xml abaixo, e continuo com erro

xml(somente o body)

   <soapenv:Body>
      <ws:todosOsItens>
      </ws:todosOsItens>
   </soapenv:Body>

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>

Erro no console:

Chamando metodo todosItens()
ago 08, 2018 9:29:12 PM com.sun.xml.internal.ws.server.sei.TieHandler createResponse
GRAVE: null
java.lang.NullPointerException
    at br.com.caelum.estoque.ws.EstoqueWS.getItens(EstoqueWS.java:27)
    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)

Oi Luiz,

Acho que o seu WSDL está incompleto.

Era para ter vindo nele as definições das classes Filtros, Filtro, ListaItens, Item e TipoItem.

Confere se todas as classes estão anotadas com @XmlRootElement.

Se quiser também pode postar aqui como está o código de todas essas classes, que eu dou uma olhadinha se tem algo errado.

Olá

Desculpe a demora, segue link para o projeto:

https://drive.google.com/file/d/1x6sSlDLSQiGeOVRH1SmSJUQOePGKUkrR/view?usp=sharing

Obrigado!!

Oi Luiz,

Testei o seu projeto e funcionou certinho.

Pode ser porque no SOAPUI, quando ele cria o request de exemplo, o xml de envio fica com ? nos parametros nome e tipo:

<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>?</tipo>
            </filtro>
         </filtros>
      </ws:todosOsItens>
   </soapenv:Body>
</soapenv:Envelope>

Mas aí você precisa alterar para algum valor, antes de disparar a requisição. Por exemplo:

<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>Moto G</nome>
               <!--Optional:-->
               <tipo>Celular</tipo>
            </filtro>
         </filtros>
      </ws:todosOsItens>
   </soapenv:Body>
</soapenv:Envelope>

Legal! Mas por favor, me ajude a entender, se a tag filtros é opcional, não poderia enviar o XML de requisição sem ela para listar todos os itens?

O XML a ser enviado seria igual a este abaixo?

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.estoque.caelum.com.br/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:todosOsItens>
      </ws:todosOsItens>
   </soapenv:Body>
</soapenv:Envelope>

Obrigado!

O parametro filtros aparece como optional, porque na classe EstoqueWS não foi definido como obrigatório.

Mas o problema de não passar os filtros vai acontecer por conta da lógica no método todosItens da classe ItemDao.

Lá até tem a verificação se está null ou vazio:

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

Mas o NullPointer acontecia porque a lista não estava vazia, mas apenas o atributo tipo do filtro. Daí dava erro nessa linha do método:

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

Então bastaria mudar essa lógica para os casos do nome ou tipo do filtro não estarem preenchidos, para que não ocorra NullPointerException.