Problema com o Unmarshal do JAXB

20 respostas
victorwss

Oi pessoal.

Tenho um problema em relação aos métodos unmarshal que retornam JAXBElement<T> da interface javax.xml.bind.Unmarshaller.

O problema é que o JAXBElement retornado traz apenas os atributos da minha tag XML, mas não trás os elementos. Debugando isso, eu vi que o QName dele (atributo name) está errado e o scope está em GlobalScope, porém tais campos são protected final e a instância do JAXBElement é criada pela implementação do Unmarshaller em algum lugar das profundezas do JAXB. Não achei nenhum método no Unmarshaller para definir o name e/ou o scope.

Alguém aí já pegou um problema parecido?

20 Respostas

victorwss

Ok, consegui resolver.

DocumentBuilderFactory dd = DocumentBuilderFactory.newInstance();
        dd.setNamespaceAware(true); // &lt;-- TAVA FALTANDO ESTA BOSTA!
G

Estou com o mesmo erro, mas mesmo setando setNamespaceAware continua. Teria como passar seu código para unmarshal.

felipeguerra

Infelizmente,

Tenho que ressuscitar esse tópico…não consigo fazer com que o Unmarshall funcione corretamente.
O erro: não há elementos na classe de resultado.

método

public void parseExplainConsultaPF(String explain) throws CrivoInterfaceException {
		JustificativaType justificativaType = null;
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance("com.example.ws"); 
			
			Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
			
			JAXBElement&lt;JustificativaType&gt; element = unmarshaller.unmarshal(new StreamSource(new StringReader(explain)), JustificativaType.class);
			
			justificativaType = element.getValue();
		       
                       //more code
	}

JAXB (generated by approach WSDL2Java)

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "JustificativaType", propOrder = {
    "justificativas"
})
public class JustificativaType {

    @XmlElement(required = true)
    protected List&lt;JustificativaTextualType&gt; justificativas;

   
    public List&lt;JustificativaTextualType&gt; getJustificativas() {
        if (justificativas == null) {
            justificativas = new ArrayList&lt;JustificativaTextualType&gt;();
        }
        return this.justificativas;
    }

no teste:

justificativaType.getJustificativas() //null

nunca retorna os elementos filhos!

Obs: XML que está sendo consumido (exatamente dessa maneira).

&lt;justificativas&gt;
&lt;justificativaTextual criterio="POLITICA_PJ" /&gt;
&lt;justificativaTextual criterio="CLIENTES - PJ"&gt;
&lt;regra&gt;
&lt;valor&gt;
&lt;texto&gt;
Cliente OK&lt;/texto&gt;
&lt;/valor&gt;
&lt;/regra&gt;
&lt;/justificativaTextual&gt;
&lt;justificativaTextual criterio="POLITICA ADIÇÃO AUTOMÁTICA - PJ"&gt;
&lt;regra&gt;
&lt;valor&gt;
&lt;texto&gt;
Aprovada no Drive de Qualidade do Crédito&lt;/texto&gt;
&lt;/valor&gt;
&lt;/regra&gt;
&lt;regra&gt;
&lt;valor&gt;
&lt;texto&gt;
Cadastro  Divergente no Sintegra&lt;/texto&gt;
&lt;/valor&gt;
&lt;/regra&gt;
&lt;/justificativaTextual&gt;
&lt;justificativaTextual criterio="ALERTA - BLACK LIST PJ"&gt;
&lt;regra&gt;
&lt;valor&gt;
&lt;texto&gt;
Aprovado no Drive de Qualidade do Crédito &lt;/texto&gt;
&lt;/valor&gt;
&lt;/regra&gt;
&lt;/justificativaTextual&gt;
&lt;justificativaTextual criterio="CADASTRO SRF"&gt;
&lt;regra&gt;
&lt;valor&gt;
&lt;texto&gt;
Municipio "Diferente" Sintegra&lt;/texto&gt;
&lt;/valor&gt;
&lt;/regra&gt;
&lt;regra&gt;
&lt;valor&gt;
&lt;texto&gt;
Estado igual a Sintegra&lt;/texto&gt;
&lt;/valor&gt;
&lt;/regra&gt;
&lt;/justificativaTextual&gt;
&lt;justificativaTextual criterio="ADIÇÃO_INADIMPLÊNCIA_PJ_ICS" /&gt;
&lt;/justificativas&gt;

Alguém pode me ajudar?

felipeguerra

alguém? o criador do tópico?

Alexandre_Saudate

Você poderia postar o código do JustificativaTextualType, também?

[]´s

felipeguerra

Você poderia postar o código do JustificativaTextualType, também?

[]´s

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "JustificativaTextualType", propOrder = {
    "regra"
})
public class JustificativaTextualType {

    protected List&lt;RegraType&gt; regra;
    @XmlAttribute(required = true)
    protected String criterio;

    
    public List&lt;RegraType&gt; getRegra() {
        if (regra == null) {
            regra = new ArrayList&lt;RegraType&gt;();
        }
        return this.regra;
    }

 
    public String getCriterio() {
        return criterio;
    }


    public void setCriterio(String value) {
        this.criterio = value;
    }

}

Valeu!

Alexandre_Saudate

Troque:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "JustificativaType", propOrder = {
    "justificativas"
})
public class JustificativaType {

    @XmlElement(required = true)
    protected List&lt;JustificativaTextualType&gt; justificativas;

   
    public List&lt;JustificativaTextualType&gt; getJustificativas() {
        if (justificativas == null) {
            justificativas = new ArrayList&lt;JustificativaTextualType&gt;();
        }
        return this.justificativas;
    }

Por

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "JustificativaType", propOrder = {
    "justificativaTextual"
})
public class JustificativaType {

    @XmlElement(required = true)
    protected List&lt;JustificativaTextualType&gt; justificativaTextual;

   
    public List&lt;JustificativaTextualType&gt; getJustificativas() {
        if (justificativaTextual == null) {
            justificativaTextual= new ArrayList&lt;JustificativaTextualType&gt;();
        }
        return this.justificativaTextual;
    }

Aqui funcionou.

Mas, que mal lhe pergunte, como você arranjou esse XML ? Ele tem um schema?

[]´s!

felipeguerra

Fiz a modificação que mencionou e ainda não funcionou…

Sobre o XML, existe um WS que devolve esse XML, porém, não há um XSD.
Eu fiz um XSD para ele pois os campos são sempre os mesmos…

Um abraço.

Alexandre_Saudate

felipeguerra:
Fiz a modificação que mencionou e ainda não funcionou…

Sobre o XML, existe um WS que devolve esse XML, porém, não há um XSD.
Eu fiz um XSD para ele pois os campos são sempre os mesmos…

Um abraço.

Não funcionou, mas continuou com o mesmo problema? Ou mudou algo?

Eu também mudei a linha

JAXBContext jaxbContext = JAXBContext.newInstance("com.example.ws");

para

JAXBContext jaxbContext = JAXBContext.newInstance(JustificativaType.class, JustificativaTextualType.class);

mas isso não deveria fazer diferença. De qualquer maneira, teste para ver se é isso.

[]´s

felipeguerra

Eu quis dizer que continua vindo NULL nos elementos filhos :

justificativaType.getJustificativaTextual() //null

asaudate:

Eu também mudei a linha

JAXBContext jaxbContext = JAXBContext.newInstance("com.example.ws");

para

JAXBContext jaxbContext = JAXBContext.newInstance(JustificativaType.class, JustificativaTextualType.class);

mas isso não deveria fazer diferença. De qualquer maneira, teste para ver se é isso.

[]´s


Infelizmente, não fez diferença mesmo. :frowning:

Alexandre_Saudate

Observe que a idéia era mudar o nome da propriedade, mesmo, não do getter. Foi isso que você fez?

[]´s

felipeguerra

asaudate:
Observe que a idéia era mudar o nome da propriedade, mesmo, não do getter. Foi isso que você fez?

[]´s


Desculpe, quem mudou foi o FMK ao gerar a classe novamente…mas eu não entendi, qual é a relação do nome da propriedade e o respectivo ‘get’ como problema?

Abraço!

Alexandre_Saudate

felipeguerra:
asaudate:
Observe que a idéia era mudar o nome da propriedade, mesmo, não do getter. Foi isso que você fez?

[]´s


Desculpe, quem mudou foi o FMK ao gerar a classe novamente…mas eu não entendi, qual é a relação do nome da propriedade e o respectivo ‘get’ como problema?

Abraço!

A classe está configurada para ter acesso direto para a propriedade. Ou seja, é o nome da propriedade que deve ser alterado. O nome do getter não faz diferença.

[]´s

Andre_Fonseca

victorwss:
Oi pessoal.

Tenho um problema em relação aos métodos unmarshal que retornam JAXBElement<T> da interface javax.xml.bind.Unmarshaller.

O problema é que o JAXBElement retornado traz apenas os atributos da minha tag XML, mas não trás os elementos. Debugando isso, eu vi que o QName dele (atributo name) está errado e o scope está em GlobalScope, porém tais campos são protected final e a instância do JAXBElement é criada pela implementação do Unmarshaller em algum lugar das profundezas do JAXB. Não achei nenhum método no Unmarshaller para definir o name e/ou o scope.

Alguém aí já pegou um problema parecido?

Vitor,

No JAXB para que ele não crie os objetos todos como inner classes quando é feito o unmarshall do xml é necessário usar escopo global, usando escopos globais é necessário usar JAXBElement

Uma outra alternativa para resolver este seu problema (trabalhar com JAXBElement definindo o QNAME) é você usar algo parecido com o código abaixo

JAXBElement&lt;MeuObjeto&gt; element = new JAXBElement(new QName( "http://example.org", "MeuObjeto", "n1"), MeuObjeto.class, results);

onde http://example.org é o seu namespace e n1 é o prefixo

felipeguerra

André Fonseca:

Vitor,

No JAXB para que ele não crie os objetos todos como inner classes quando é feito o unmarshall do xml é necessário usar escopo global, usando escopos globais é necessário usar JAXBElement

Uma outra alternativa para resolver este seu problema (trabalhar com JAXBElement definindo o QNAME) é você usar algo parecido com o código abaixo

JAXBElement&lt;MeuObjeto&gt; element = new JAXBElement(new QName( &quot;http://example.org&quot;, &quot;MeuObjeto&quot;, &quot;n1&quot;), MeuObjeto.class, results);

onde http://example.org é o seu namespace e n1 é o prefixo


Não entendi a aplicação no meu caso, onde o WSDL que originou as classes, é algo mais ou menos assim:

&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
&lt;wsdl:definitions xmlns:tns="http://www.example.com/Consulta/" 
				xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
				xmlns:s="http://www.w3.org/2001/XMLSchema" name="ConsultaCrivo" targetNamespace="http://www.example.com/Consulta/" 
				xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"&gt;
&lt;wsdl:types&gt;
	&lt;s:schema targetNamespace="http://www.example.com/Consulta/" elementFormDefault="qualified"&gt;

            &lt;s:complexType name="JustificativaType"&gt;
	    	&lt;s:sequence&gt;
				&lt;s:element name="justificativaTextual" minOccurs="1" maxOccurs="unbounded" type="tns:JustificativaTextualType"&gt;&lt;/s:element&gt;
	    	&lt;/s:sequence&gt;
	    &lt;/s:complexType&gt;
	    
	    &lt;s:complexType name="JustificativaTextualType"&gt;
	    	&lt;s:sequence&gt;
	    		&lt;s:element name="regra" minOccurs="0" maxOccurs="unbounded" type="tns:RegraType"&gt;&lt;/s:element&gt;
	    	&lt;/s:sequence&gt;
	    	&lt;s:attribute name="criterio" use="required" type="s:string"&gt;&lt;/s:attribute&gt;
	    &lt;/s:complexType&gt;
		
		&lt;s:complexType name="RegraType"&gt;
	    	&lt;s:sequence&gt;
	    		&lt;s:element name="valor" type="tns:ValorType" minOccurs="0" maxOccurs="unbounded"&gt;&lt;/s:element&gt;
	    	&lt;/s:sequence&gt;
	    &lt;/s:complexType&gt;
	    
	    &lt;s:complexType name="ValorType"&gt;
	    	&lt;s:sequence&gt;
	    		&lt;s:element name="texto" minOccurs="0" maxOccurs="1" type="s:string"&gt;&lt;/s:element&gt;
	    	&lt;/s:sequence&gt;
	    &lt;/s:complexType&gt;
       &lt;/s:schema&gt;

       &lt;!--  restante suprimido --&gt;

&lt;/wsdl:types&gt;
&lt;/wsdl:definitions&gt;
Alexandre_Saudate

Felipe,

Dê uma olhada no código que estou colocando em anexo… é o teste que eu rodei aqui.

[]´s

Andre_Fonseca

[quote=felipeguerra]

André Fonseca:

Não entendi a aplicação no meu caso, onde o WSDL que originou as classes, é algo mais ou menos assim:

Não seria para o seu caso, esse código que postei serve para trabalhar com o Escopo Global de objetos anotados que não possuem o XMLRootElement (foi o que o Victor falou no primeiro post)

[]´s

felipeguerra

André Fonseca:
felipeguerra:

Não entendi a aplicação no meu caso, onde o WSDL que originou as classes, é algo mais ou menos assim:

Não seria para o seu caso, esse código que postei serve para trabalhar com o Escopo Global de objetos anotados que não possuem o XMLRootElement (foi o que o Victor falou no primeiro post)

[]´s


Entendido!

valeu

felipeguerra

asaudate:
Felipe,

Dê uma olhada no código que estou colocando em anexo… é o teste que eu rodei aqui.

[]´s


O meu código está igual no que tange a forma, ou seja, usei de classes diferentes para fazer a mesma coisa que o seu código…porém, ainda não funciona.

Se eu conseguisse depurar o FMK…

felipeguerra

Pessoal, resolvi o problema, agreguei o cabeçalho e o namespace ao XML de entrada e pronto!

Criado 23 de janeiro de 2008
Ultima resposta 3 de dez. de 2010
Respostas 20
Participantes 5