Pergunta

Tentando passar uma exceção de lançamento de classe aqui:

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);

lança essa exceção:

java.lang.ClassCastException: javax.xml.bind.JAXBElement

Eu não entendo isso - como a classe foi gerado pela ferramenta xjc.bat - e as classes que gerou Eu não alteraram em tudo - por isso não deve haver problemas de fundição aqui - o unmarshaller deve realmente estar me dando apoiar uma classe que pode ser convertido para FooClass.

Todas as ideias sobre o que estou fazendo de errado?

Foi útil?

Solução

O FooClass ter a anotação XmlRootElement? Se não, tente:

Source source = new StreamSource(inputStream);
JAXBElement<FooClass> root = unmarshaller.unmarshal(source, FooClass.class);
FooClass foo = root.getValue();

Isso é baseado na Unofficial Guia JAXB .

Outras dicas

Use JAXBIntrospector na JAXBElement para obter o schemaObject como >>

JAXBContext jaxbContext = JAXBContext.newInstance(Class.forName(className));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object schemaObject = JAXBIntrospector.getValue(unmarshaller.unmarshal(new ByteArrayInputStream(xmlString.getBytes())));

Consulte: quando faz JAXB retornos unmarshaller.unmarshal um JAXBElement ou um MySchemaObject?

Eu corri para o mesmo problema hoje, viu as respostas aqui, fiz algumas pesquisas e parece-me que a solução mais genérica é usar JAXBIntrospector . Daí -

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);

deve ser escrita como

FooClass fooClass = (FooClass) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));

Ou melhor ainda, para torná-lo mais genérico -

T t = (T) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));

Para uma explicação mais completa leia este artigo . Acontece que o XSD deve ser configurado corretamente, ou seja, deve haver algum elemento de raiz que engloba todos os outros elementos.

XJC não tentar colocar anotação @XmlRootElement em uma classe que geramos a partir de um tipo complexo. A condição exata é um pouco feio, mas a idéia básica é que se pode estaticamente garantia de que um tipo complexo não será utilizado por vários nomes de marcas diferentes, colocamos @XmlRootElement.

Eu olhava para o arquivo XML e verifique se ele é mais ou menos o que você espera para ver.

Eu também alterar temporariamente o código para:

Object o = unmarshaller.unmarshal(inputStream);
System.out.println(o.getClass());

se o primeiro falhas então o elenco classe está acontecendo dentro do método unmarshal, se for bem sucedido, então você pode ver a classe real que você está ficando para trás e, em seguida, descobrir por que ele não é o que você espera que ele seja.

Passamos muitas horas brincando com a classe JAXB fábrica para satisfazer o unmarshaller. Nós aprendemos que a utilização do unmarshaller sem de chamar a fábrica de objeto gerado pelo JAXB funciona bem. Espero frustração da amostra redime código de alguém:

System.out.println("Processing generic-type unmarshaller: ");
MessageClass mcObject = unmarshalXml(MessageClass.class, msgQryStreamSource,
    NAMESPACE + "." + "MessageClass");

public static <T> T unmarshalXml(Class<T> clazz, StreamSource queryResults,
    String contextNamespace)
    {
        T resultObject = null;
        try {
            //Create instance of the JAXBContext from the class-name
            JAXBContext jc;
            jc = JAXBContext.newInstance(Class.forName(clazz.getName()));
            Unmarshaller u = jc.createUnmarshaller();
            resultObject = clazz.cast(u.unmarshal(queryResults));
            }
              //Put your own error-handling here.
        catch(JAXBException e)
        {
            e.printStackTrace();
        }
        catch (ClassCastException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        return clazz.cast(resultObject);
    }

Com base nos previews respostas de colegas, apenas no caso de alguém está ainda à procura de uma resposta.

Eu tive o problema de ter o elemento raiz do meu esquema é definido como:

<schema>
  <element name="foo" type="bar" />
  <complexType name="bar" />
</schema>

E, portanto, eu estava ficando um exceção de elenco em:

try {            
        javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getPackage().getName());            
        javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
        File f = FileUtil.toFile(this.getPrimaryFile());            
        mobilityConfigType = (MobilityModelConfigType)unmarshaller.unmarshal(FileUtil.toFile(this.getPrimaryFile()));
    } catch (javax.xml.bind.JAXBException ex) {            
        java.util.logging.Logger.getLogger("global").log(java.util.logging.Level.SEVERE, null, ex); //NOI18N
    }

O que fiz foi mudar a primeira linha do bloco try para:

javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getName());

Isso resolveu o problema para mim.

Você está absolutamente certo FooClass é o elemento raiz da fonte de entrada xml que você passou? Desempacotar irá retornar um objeto do elemento raiz criado por xjc.

Às vezes você tem uma definição XSD com vários elementos raiz diferentes (por exemplo XSD definido no WSDL) e, nesse caso, as classes geradas estão faltando @XmlRootElement. Assim como mbrauh usuário já escreveu você tem que obter o valor de JAXBElement. No meu caso eu usei:

FooClass request = ((JAXBElement< FooClass >) marshaller.unmarshal(new StreamSource(classPathResource.getInputStream()))).getValue();

Então, usando os genéricos você pode facilmente evitar vazamento tipo double.

Especifique @XmlRootElement (name = "specifyname", namespace = "namespace") para transformar objeto.

Eu também encontrou o "Javax.xml.bind.JAXBElement não pode ser convertido para" erro e encontrei esta solução muito simples:

FooClass fooClass = (FooClass) ((JAXBElement) u.unmarshal(new File("xml/foo.xml")) ).getValue();

Uma vez que, aparentemente, um objeto do tipo JAXBElement é retornado, você precisa estereotipado seu valor.

Fonte: https://forums.oracle.com/thread/1625944

Tente isto:

JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement element = (JAXBElement) unmarshaller.unmarshal( new StringReader(xmlString));
Foo foo = (Foo)element;

No meu caso, eu recebo o erro ao tentar enviar uma petição sabão a partir da aplicação SOAPUI. Eu preciso definir a propriedade 'espaços em branco strip' para true para ignorar este erro.

Quando depurar o conteúdo recebido, é uma lista com o seguinte conteúdo:

[0] = "\n"
[1] = JAXBElement
[2] = "\n"

Hope ajuda alguém.

Se você tem acesso e você pode modificar o XSD. Para mim, esta questão acrescenta quando eu gerar o XSD a partir de XML com IDEA.

Com este xml:

<?xml version="1.0"?>
<schema>
  <element name="foo" type="bar" />
  <complexType name="bar" />
</schema>

IDEA gerar um XSD assim e JAXB não irá gerar um elemento de raiz:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="schema" type="schemaType"/>
  <xs:complexType name="schemaType">
    <xs:sequence>
      <xs:element type="elementType" name="element"/>
      <xs:element type="complexTypeType" name="complexType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="elementType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
        <xs:attribute type="xs:string" name="type"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="complexTypeType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:schema>

Mas, se você modificar o XSD dessa maneira (modifique o seu elemento raiz "esquema", a fim de obter a xs: complexType dentro dos xs tag: Elemento):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="schema">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="elementType" name="element"/>
        <xs:element type="complexTypeType" name="complexType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="schemaType">
    <xs:sequence>
      <xs:element type="elementType" name="element"/>
      <xs:element type="complexTypeType" name="complexType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="elementType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
        <xs:attribute type="xs:string" name="type"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="complexTypeType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="name"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:schema>

JAXB irá gerar o elemento de raiz!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top