استثناء فئة Cast عند محاولة إلغاء تنظيم XML؟

StackOverflow https://stackoverflow.com/questions/707084

  •  22-08-2019
  •  | 
  •  

سؤال

محاولة تجاوز استثناء الفصل الدراسي هنا:

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

يلقي هذا الاستثناء:

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

لا أفهم هذا - حيث تم إنشاء الفصل بواسطة أداة xjc.bat - ولم أغير الفئات التي أنشأتها على الإطلاق - لذلك لا ينبغي أن تكون هناك مشكلات في الإرسال هنا - يجب أن يعيدني برنامج إلغاء التنظيم حقًا إلى فصل دراسي التي يمكن إرسالها إلى FooClass.

أي أفكار حول ما أفعله خطأ؟

هل كانت مفيدة؟

المحلول

هل FooClass يكون الشرح XmlRootElement؟ إن لم يكن، في محاولة:

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

وهذا على أساس غير رسمي دليل JAXB .

نصائح أخرى

استخدم JAXBIntrospector على JAXBElement للحصول على schemaObject مثل >>

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

وراجع: متى JAXB unmarshaller.unmarshal إرجاع JAXBElement أو MySchemaObject؟

لقد واجهت نفس المشكلة اليوم، وشاهدت الإجابات هنا، وأجريت بعض الأبحاث وتبين لي أن الحل الأكثر عمومية هو الاستخدام JAXBIntrospector.لذلك -

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

ينبغي أن تكون مكتوبة كما

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

أو حتى أفضل لجعلها أكثر عمومية -

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

لشرح أكمل قراءة <لأ href = "http://web.archive.org/web/20090121025810/http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html "يختلط =" noreferrer نوفولو "> هذه المقالة . وتبين أن XSD الخاص بك يجب أن يتم تعيين بشكل صحيح، أي يجب أن يكون هناك بعض العناصر الجذرية التي تشمل جميع العناصر الأخرى.

<اقتباس فقرة>   

وXJC لا أحاول أن أضع الشرح @XmlRootElement على فئة أننا نولد من نوع معقد. حالة بالضبط قبيحة إلى حد ما، ولكن الفكرة الأساسية هي أنه إذا كان يمكننا أن نضمن بشكل ثابت أن نوع معقد لن يتم استخدامها من قبل العديد من أسماء العلامات المختلفة، وضعنا @XmlRootElement.

وأود أن ننظر في ملف XML وللتأكد من ما يقرب من ما كنت تتوقع أن ترى.

وكنت أيضا تغيير رمز مؤقتا إلى:

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

وإذا كان failes واحد الأولى ثم يلقي الطبقة يحدث داخل طريقة unmarshal، إذا نجحت ثم يمكنك ان ترى الطبقة الفعلية التي كنت تحصل الوراء و من ثم معرفة لماذا هو غير ما تتوقع أن يكون.

وقضينا ساعات كثيرة جدا التململ مع الطبقة مصنع JAXB لتلبية unmarshaller. لقد تعلمنا أن استخدام unmarshaller <م> بدون استدعاء المصنع الكائن ولدت JAXB-يعمل على ما يرام. آمل أن نموذج التعليمات البرمجية يعوض الإحباط شخص ما:

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

وبناء على إجابات معاينات من الزملاء، فقط في حالة أي شخص لا يزال يبحث عن إجابة.

وكان لي قضية وجود العنصر الجذر مخطط بلدي التي تعرف بأنها:

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

وبالتالي كنت الحصول على استثناء المصبوب على العنوان التالي:

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
    }

ما فعلته كان لتغيير السطر الأول من كتلة محاولة ل:

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

وهذا حل المشكلة بالنسبة لي.

هل أنت متأكد تماما FooClass هو العنصر الجذر من مصدر XML الإدخال الذي مرت عليه؟ Unmarshall سيعود كائن من العنصر الجذر التي أنشأتها xjc.

وأحيانا يكون لديك تعريف XSD مع العناصر الجذر مختلفة متعددة (على سبيل المثال XSD المحددة في WSDL) وفي هذه الحالة الفئات التي تم إنشاؤها مفقودةXmlRootElement. وذلك mbrauh المستعمل كتب بالفعل لديك للحصول على قيمة JAXBElement. في حالتي أنا استخدم:

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

وذلك باستخدام الأدوية يمكنك بسهولة تجنب نوع مزدوج الصب.

وحددXmlRootElement (اسم = "specifyName"، مساحة الاسم = "مساحة") لتحويل الكائن.

وأنا أيضا واجهت "لا يمكن أن يلقي Javax.xml.bind.JAXBElement إلى" خطأ وجدت هذا الحل بسيط جدا:

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

ومنذ ذلك الحين، على ما يبدو، يتم إرجاع كائن من نوع JAXBElement، تحتاج إلى التلبيس قيمتها بدلا من ذلك.

المصدر: https://forums.oracle.com/thread/1625944

وجرب هذا:

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

في حالتي، وأحصل على خطأ عند محاولة إرسال عريضة الصابون من تطبيق SOAPUI. ولست بحاجة لتعيين الخاصية "الفراغات قطاع" إلى true لتخطي هذا الخطأ.

عند تصحيح محتوى وردت، هي قائمة مع المحتوى القادم:

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

والأمل مساعدة شخص ما.

إذا كان لديك الوصول ويمكنك تعديل XSD. بالنسبة لي، بإلحاق هذه المسألة عندما تولد XSD من XML مع IDEA.

ومع هذا XML:

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

وIDEA توليد XSD من هذا القبيل، وسوف JAXB لا تولد عنصر الجذر:

<?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>

ولكن، في حالة تعديل XSD بهذه الطريقة (تعديل العنصر الجذر "المخطط" من أجل الحصول على XS: complexType داخل علامة XS: عنصر):

<?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 سوف تولد عنصر الجذر!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top