Remover prefix namespace JAX-WS

32 respostas
cristiano.andrade

Pessoal,

Estou acessando um WS com JAX-WS e preciso retirar o prefixo do namespace quando ele envia o XML. O xml é gerado sem prefixos, mas quando ele envia os prefixos aparecem :S

Exemplo:

O XML é enviado assim:

<ns4:tpAmb>2</ns4:tpAmb>
<ns4:nRec>03000000000878</ns4:nRec>

Gostaria de retirar esses prefixos “ns4”, será que isso é possivel ? alguem já passou por isso?

[]s

32 Respostas

Lucas_Cavalcanti

Se o seu modelo é dependente de namespace, pq vc quer tirar os prefixos??

cristiano.andrade

Por que estou desenvolvendo um sistema parecido com a nota fiscal eletronica… e no manual o web service deles exige isso :cry:

Existe alguma forma de fazer isso?

Lucas_Cavalcanti

Suponha que o cliente do seu serviço se chame NotaFiscalService

é só vc fazer algo do tipo:

Service service = new NotaFiscalService(new URL("http://qualquerlugar"),
                new QName("http://namespace", "nomeDoServico", "prefixo"));

e no lugar do “prefixo” é soh colocar “”

só não pode ter mais de um namespace mapeado pra “”

quando for pegar o Port também dá pra especificar um QName… e é soh colocar
o prefixo vazio tb…

cristiano.andrade

Fiz exatamente o que voce disse e ainda continuo com esse problema :frowning:

Estou passando um objeto Document como parametro … ser que pode ser isso?

[]

Lucas_Cavalcanti

Tenta algo do tipo então:

Document d = ...;

d.setPrefix("");

talvez vc tenha que tirar a passagem de prefixos no QName… mas isso deve funcionar…

cristiano.andrade

Lucas,

Não sei mais o que fazer continua do mesmo jeito!

Da uma olhada no request do WS.

---[HTTP request]---
SOAPAction: ""
Accept: application/soap+xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: application/soap+xml;charset="utf-8";action="http://www.portalfiscal.inf.br/cte/wsdl/
CteRetRecepcao/cteRetRecepcao"
<?xml version="1.0" ?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Header><cteCabecMsg xmlns="http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao">
<cUF>0</cUF>
<versaoDados>1.00</versaoDados>
</cteCabecMsg>
</S:Header>
<S:Body>
<cteDadosMsg xmlns="http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao">
<consReciCTe:consReciCTe xmlns:consReciCTe="http://www.portalfiscal.inf.br/cte" xmlns="" 
xmlns:ns4="http://www.portalfiscal.inf.br/cte" versao="1.00">
<ns4:tpAmb>2</ns4:tpAmb>
<ns4:nRec>03000000000878</ns4:nRec>
</consReciCTe:consReciCTe>
</cteDadosMsg>
</S:Body>
</S:Envelope>

como voce o processo de importação do ws é com o wsimport?

[]

Lucas_Cavalcanti

já tem um namespace sem prefixo, o http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao,

e só pode ter um namespace por prefixo.

qdo tah xmlns=“namespace” quer dizer q o namespace vai ficar sem prefixo
se tiver xmlns:qqer=“namespace” quer dizer q o namespace vai ficar com o prefixo qqer…

de qqer coisa, eu acho q vc vai ter que colocar o xml que vc precisa q esteja sem prefixo
dentro de um CDATA

algo como

<cteDadosMsg xmlns="http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao">  
<!CDATA[
 <consReciCTe xmlns="http://www.portalfiscal.inf.br/cte" versao="1.00">  
 <tpAmb>2</tpAmb>  
 <nRec>03000000000878</nRec>  
 </consReciCTe>  
]!>
 </cteDadosMsg>

ou sei lah… vc vai ter que de algum jeito colocar um prefixo no namespace
http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao e tirar o prefixo no namespace
http://www.portalfiscal.inf.br/cte

vc vai poder fazer isso fazendo algo do tipo:

Service service = new NotaFiscalService(new URL("http://qualquerlugar"),
                new QName("http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao", "CteRetRecepcao", "nfp"));
NotaFiscalServicePort port = service.getPort(new QName("http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao",
              "CteRetRecepcao_Port", "nfp"), NotaFiscalServicePort.class);
Document d = ...;//cria o documento de algum jeito
d.setPrefix("");
port.notaFiscalOperation(d);

me manda o código que vc tah usando pra invocar o webservice

cristiano.andrade

Chamo desse jeito:

CteRetRecepcao service = new CteRetRecepcao(new URL("file:/home/cristiano/CteRetRecepcao.wsdl")
            , new QName("http://www.portalfiscal.inf.br/cte/wsdl/CteRetRecepcao", "CteRetRecepcao","cte"));
            CteRetRecepcaoSoap12 port = service.getCteRetRecepcaoSoap12();

            CteDadosMsg cteDadosMsg = new CteDadosMsg();
   
            Document xml = getDocument();
            
            cteDadosMsg.getContent().add(xml.getDocumentElement());

            CteCabecMsg cteCabecMsg = new CteCabecMsg();
            cteCabecMsg.setCUF("0");
            cteCabecMsg.setVersaoDados("1.00");

            Holder<CteCabecMsg> holder = new Holder<CteCabecMsg>(cteCabecMsg);
            
            result = port.cteRetRecepcao(cteDadosMsg, holder);
Lucas_Cavalcanti

vc tentou o

xml.setPrefix("");

ou

xml.getDocumentElement().setPrefix("");

??

cristiano.andrade

Já tentei :slight_smile:

Lucas_Cavalcanti

tenta usar a ferramenta wsimport pra gerar as classes de modelo a partir do wsdl

assim vc não precisa ficar manipulando a árvore DOM, que é bastante feio é suscetivel a erros…

https://jax-ws.dev.java.net/jax-ws-ea3/docs/wsimport.html

se mesmo assim vc precisar trabalhar com árvores DOM dê uma olhada no JAXB
(JAXBFactory, Marshaller, Unmarshaller, ambos trabalham com DOM)

[]'s

cristiano.andrade

E o pior de tudo é que eu usei o wsdlimport e estou trabalhando com objetos !

O problema é que tenho uma lista e tenho que passar um xml no seu conteudo.

Quando passo uma String os caracteres ficam desconfigurados.

Tipo:

&lt;ns1:consReciCTe ns1:versao="1.00" xmlns:ns1="http://www.portalfiscal.inf.br/cte"&gt;
    &lt;ns1:tpAmb&gt;2&lt;/ns1:tpAmb&gt;
    &lt;ns1:nRec&gt;03000000000887&lt;/ns1:nRec&gt;
&lt;/ns1:consReciCTe&gt;

E ai tenho que passar um Document… por isso que da esse erro e eu não consigo mudar o prefix do namespace.

Se eu passar uma string ele vai do jeito que eu quero

Sera que tem como eu passar essa String sem ter esses caracteres malucos?

cristiano.andrade

os caracteres não apareceram eles são o "e comercial " seguidos de lt ou gt

Lucas_Cavalcanti

sim… se vc passar um xml por string, ele vai escapar os caracteres reservados para o xml
como o < = < e o > = >

cristiano.andrade

Tem como eu passar string sem escapar esses caracteres?

Lucas_Cavalcanti

só se a string estiver dentro de um CDATA…
caso contrario ela seria interpretada como um pedaço de xml…

cristiano.andrade

tentei colocar num e ainda mostra caracteres especiais. :frowning:

estou quase desistindo disso rsrs

Lucas_Cavalcanti

colocar num CDATA não é colocar:

String xml = "<blah></blah>";
xml = "<!CDATA[" + xml + "]>";

é fazer algo como:

Document d;
d.createCDATA(xml);

não lembro como usa, mas é algo do tipo…

[]'s

C

Pessoal,

tendo o arquivo XML gerado, como passo para o objeto cteDadosMsg? É diferente da NFe, que normalmente tratava tudo como String.

Dá pra fazer isso?

Obrigado

C

Ninguém?

cristiano.andrade

Para fazer isso você pode usar o JAXB https://jaxb.dev.java.net

C

Na verdade estou utilizando o NetBeans para criação de uma classe de comunicação, assim como foi feito para a NF-e. O problema é que como o CT-e não segue o padrão da NF-e, onde o método era chamado com 2 parâmetros String (cabeçalho e dados), ainda não consegui passar as informações para o objeto cteDadosMsg.

Eu já possuo o XML gerados, tudo que eu preciso é passar para a classe cteDadosMsg.

Poderia dar uma dica? No projeto de NF-e, eu jogava os dados do XML para Strings e estava ok.

Obrigado

cristiano.andrade

Você já importou o WS com o wsimport para gerar as classes?

C

Não, eu gerei as classes diretamente no NetBeans utilizando o WSDL. O que ele gera é:

try { // Call Web Service Operation

br.inf.portalfiscal.cte.wsdl.ctestatusservico.CteStatusServico service = new br.inf.portalfiscal.cte.wsdl.ctestatusservico.CteStatusServico();

br.inf.portalfiscal.cte.wsdl.ctestatusservico.CteStatusServicoSoap12 port = service.getCteStatusServicoSoap12();

// TODO initialize WS operation arguments here

br.inf.portalfiscal.cte.wsdl.ctestatusservico.CteDadosMsg cteDadosMsg = new br.inf.portalfiscal.cte.wsdl.ctestatusservico.CteDadosMsg();

// TODO process result here

br.inf.portalfiscal.cte.wsdl.ctestatusservico.CteStatusServicoCTResult result = port.cteStatusServicoCT(cteDadosMsg);

System.out.println("Result = "+result);

} catch (Exception ex) {

// TODO handle custom exceptions here

}

Muito similar ao que gerava para NF-e. O que eu não estou sabendo fazer é passar os dados dos XML, que já tenho em variáveis String para o objeto cteDadosMsg.

Obrigado novamente!

cristiano.andrade

Então, você já tem o objeto cteDadosMsg o que voce precisa fazer é fazer o binding usando o JAXB.

O JAXB possui duas classes que ajudam fazer isso uma delas é o Marshaller que transforma o objeto java em XML.

Outra é o UnMarshaller que transforma o XML em Objeto.

Exemplo:

String xml = "...."

JAXBContext jaxbContext=JAXBContext.newInstance(CteDadosMsg.class);

Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
JAXBElement<CteDadosMsg> element = (JAXBElement<CteDadosMsg>) 
unMarshaller.unmarshal(new StreamSource(new ByteArrayInputStream(xml.getBytes())),CteDadosMsg.class);

CteDadosMsg cteDadosMsg = element.getValue();

Esse link pode te ajudar melhor:
http://onjava.com/pub/a/onjava/2004/12/15/jaxb.html

torquatro

cristiano.andrade vc conseguiu resolver esse problema do namespace?

Estou exatamente com o mesmo problema na NF-e.
Qdo adiciono um Document xml no meu objeto NfeDadosMsg na tag infCanc, ele adiciona o namespace e um xmlns="" (vazio)

Olha só o xml gerado:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Header>
        <ns2:nfeCabecMsg xmlns:ns2="http://www.portalfiscal.inf.br/nfe/wsdl/NfeCancelamento2" xmlns="http://www.portalfiscal.inf.br/nfe">
                <ns2:cUF>41</ns2:cUF>
                <ns2:versaoDados>2.00</ns2:versaoDados>
        </ns2:nfeCabecMsg>
</S:Header>
<S:Body>
<ns2:nfeDadosMsg xmlns:ns2="http://www.portalfiscal.inf.br/nfe/wsdl/NfeCancelamento2" xmlns="http://www.portalfiscal.inf.br/nfe">
<cancNFe versao="2.00">
  <infCanc xmlns="" xmlns:ns3="http://www.portalfiscal.inf.br/nfe" Id="ID41101206065256000163550010000005040001194848">
    <ns3:tpAmb>2</ns3:tpAmb>
    <ns3:xServ>CANCELAR</ns3:xServ>
    <ns3:chNFe>41101206065256000163550010000005040001194848</ns3:chNFe>
    <ns3:nProt>[telefone removido]</ns3:nProt>
    <ns3:xJust>alguma justificativa generica</ns3:xJust>
  </infCanc>
</cancNFe>
</ns2:nfeDadosMsg>
</S:Body>
</S:Envelope>

O estranho é que só aparece esse xmlns="" qdo o xml tem algum atributo, como por exemplo o Id=“ID41101206065256000163550010000005040001194848”

Se puder me dar uma luz ficaria muito agradecido.

Marcelo_Bento

Amigo… alguem conseguiu retirar esses prefixos <ns2: do XML ?

torquatro

Então. Não consegui remover. :stuck_out_tongue:

Tive que criar um envelope soup na mão.

aix

para remover esses prefixos indesejáveis precisa implementar esta interface: NamespacePrefixMapper

segue: https://blogs.oracle.com/enterprisetechtips/entry/customizing_jaxb

Marcelo_Bento

Diferente dessas pessoas que somente diz que resolveu e não posta a solução, vou postar aqui como consegui resolver, de todas foi a mais fáil que achei :

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.meunamespace.inf.br",
		xmlns =
		  {
		    @javax.xml.bind.annotation.XmlNs(prefix = "",
		      namespaceURI="http://www.meunamespace.inf.br")
		  },
		elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)	
package br.inf.portalfiscal.nfe;

Criei o arquivo package-info.java, coloquei dentro da pasta onde gera o XML e funfou perfeitamente.

aix

Marcelo Bento:

Diferente dessas pessoas que somente diz que resolveu e não posta a solução, vou postar aqui como consegui resolver, de todas foi a mais fáil que achei :
Criei o arquivo package-info.java, coloquei dentro da pasta onde gera o XML e funfou perfeitamente.

se esta usando o JAX-WS essa sua solução só serve para a geração do XML quando for enviar para a sefaz na versão 1.2 do SOAP que precisa enviar os dados com o tipo mime XML e não String como se faz no Axis2 não ira funcionar pois precisa colocar o objeto e ainda tem os dados do cabeçalho o máximo que consegue com sua solução é consumir o status do serviço falo se usar JAX-WS, abraços.

Marcelo_Bento

Olá AIX, blz?

Cara… comigo funcionou filet e obtive os restornos esperados!

Abraço.

Criado 3 de julho de 2008
Ultima resposta 7 de fev. de 2013
Respostas 32
Participantes 6