Problema com o Unmarshal do JAXB

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?

Ok, consegui resolver.

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

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

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?

alguém? o criador do tópico?

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

[]´s

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

[]´s[/quote]

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

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!

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.

[quote=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.[/quote]

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

Eu quis dizer que continua vindo NULL nos elementos filhos :

justificativaType.getJustificativaTextual() //null

[quote=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[/quote]
Infelizmente, não fez diferença mesmo. :frowning:

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

[]´s

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

[]´s[/quote]
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!

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

[]´s[/quote]
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![/quote]

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

[quote=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?[/quote]

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

[quote=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[/quote]
Não entendi a aplicação no meu caso, onde o WSDL que originou as classes, é algo mais ou menos assim:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&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;

Felipe,

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

[]´s

[quote=felipeguerra][quote=André Fonseca]

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

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

[quote=André Fonseca][quote=felipeguerra]

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

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
[/quote]
Entendido!

valeu

[quote=asaudate]Felipe,

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

[]´s[/quote]
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…