Remover prefix namespace JAX-WS

32 respostas
C

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

L

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

C

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?

L

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…

C

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?

[]

L

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…

C

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?

[]

L

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

C

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

vc tentou o

xml.setPrefix("");

ou

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

??

C

Já tentei :slight_smile:

L

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

C

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?

C

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

L

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

C

Tem como eu passar string sem escapar esses caracteres?

L

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

C

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

estou quase desistindo disso rsrs

L

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?

C

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

C

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!

C

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

T

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.

M

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

T

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

Tive que criar um envelope soup na mão.

A

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

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

M

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.

A

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.

M

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