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); // <-- 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<JustificativaType> 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<JustificativaTextualType> justificativas;
public List<JustificativaTextualType> getJustificativas() {
if (justificativas == null) {
justificativas = new ArrayList<JustificativaTextualType>();
}
return this.justificativas;
}
no teste:
justificativaType.getJustificativas() //null
nunca retorna os elementos filhos!
Obs: XML que está sendo consumido (exatamente dessa maneira).
<justificativas>
<justificativaTextual criterio="POLITICA_PJ" />
<justificativaTextual criterio="CLIENTES - PJ">
<regra>
<valor>
<texto>
Cliente OK</texto>
</valor>
</regra>
</justificativaTextual>
<justificativaTextual criterio="POLITICA ADIÇÃO AUTOMÁTICA - PJ">
<regra>
<valor>
<texto>
Aprovada no Drive de Qualidade do Crédito</texto>
</valor>
</regra>
<regra>
<valor>
<texto>
Cadastro Divergente no Sintegra</texto>
</valor>
</regra>
</justificativaTextual>
<justificativaTextual criterio="ALERTA - BLACK LIST PJ">
<regra>
<valor>
<texto>
Aprovado no Drive de Qualidade do Crédito </texto>
</valor>
</regra>
</justificativaTextual>
<justificativaTextual criterio="CADASTRO SRF">
<regra>
<valor>
<texto>
Municipio "Diferente" Sintegra</texto>
</valor>
</regra>
<regra>
<valor>
<texto>
Estado igual a Sintegra</texto>
</valor>
</regra>
</justificativaTextual>
<justificativaTextual criterio="ADIÇÃO_INADIMPLÊNCIA_PJ_ICS" />
</justificativas>
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<RegraType> regra;
@XmlAttribute(required = true)
protected String criterio;
public List<RegraType> getRegra() {
if (regra == null) {
regra = new ArrayList<RegraType>();
}
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<JustificativaTextualType> justificativas;
public List<JustificativaTextualType> getJustificativas() {
if (justificativas == null) {
justificativas = new ArrayList<JustificativaTextualType>();
}
return this.justificativas;
}
Por
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "JustificativaType", propOrder = {
"justificativaTextual"
})
public class JustificativaType {
@XmlElement(required = true)
protected List<JustificativaTextualType> justificativaTextual;
public List<JustificativaTextualType> getJustificativas() {
if (justificativaTextual == null) {
justificativaTextual= new ArrayList<JustificativaTextualType>();
}
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: :frowning:](https://www.guj.com.br/images/emoji/twitter/frowning.png?v=9)
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<MeuObjeto> 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<MeuObjeto> 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]
Não entendi a aplicação no meu caso, onde o WSDL que originou as classes, é algo mais ou menos assim:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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/">
<wsdl:types>
<s:schema targetNamespace="http://www.example.com/Consulta/" elementFormDefault="qualified">
<s:complexType name="JustificativaType">
<s:sequence>
<s:element name="justificativaTextual" minOccurs="1" maxOccurs="unbounded" type="tns:JustificativaTextualType"></s:element>
</s:sequence>
</s:complexType>
<s:complexType name="JustificativaTextualType">
<s:sequence>
<s:element name="regra" minOccurs="0" maxOccurs="unbounded" type="tns:RegraType"></s:element>
</s:sequence>
<s:attribute name="criterio" use="required" type="s:string"></s:attribute>
</s:complexType>
<s:complexType name="RegraType">
<s:sequence>
<s:element name="valor" type="tns:ValorType" minOccurs="0" maxOccurs="unbounded"></s:element>
</s:sequence>
</s:complexType>
<s:complexType name="ValorType">
<s:sequence>
<s:element name="texto" minOccurs="0" maxOccurs="1" type="s:string"></s:element>
</s:sequence>
</s:complexType>
</s:schema>
<!-- restante suprimido -->
</wsdl:types>
</wsdl:definitions>
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…