سؤال

أنا أحاول أن تولد فئات Java من FpML (Finanial المنتجات Markup Language) الإصدار 4.5.الكثير من التعليمات البرمجية تم إنشاؤه, ولكن أنا لا يمكن استخدامها.محاولة إجراء تسلسل بسيط الوثيقة أحصل على هذا:

javax.xml.bind.MarshalException
  - with linked exception: [com.sun.istack.SAXException2: unable
  to marshal type
  "org.fpml._2008.fpml_4_5.PositionReport"
  as an element because it is missing an
  @XmlRootElement annotation]

في الواقع لا classses لديهم @XmlRootElement الشرح ، ماذا يمكن أن أفعل الخطأ؟.أنا لافتا xjc (JAXB 2.1) إلى fpml-الرئيسية-4-5.xsd, ثم الذي يشمل جميع أنواع.

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

المحلول

أن تربط الآخرين ما سبق أن صرح أو ألمح في القواعد التي JAXB XJC يقرر ما إذا كان أو عدم وضع @XmlRootElement الشرح على إنشاء فئة غير تافهة (راجع هذه المقالة).

@XmlRootElement موجود لأن JAXB وقت يتطلب بعض المعلومات من أجل المشير/unmarshal معين كائن على وجه التحديد عنصر XML اسم مساحة الاسم.لا يمكنك فقط تمرير أي كائن إلى Marshaller. @XmlRootElement يوفر هذه المعلومات.

الشرح هو مجرد الراحة ، ومع ذلك - JAXB لا تتطلب ذلك.البديل هو استخدام JAXBElement المجمع الكائنات التي تقدم نفس المعلومات @XmlRootElement, ولكن في شكل كائن بدلا من الشرح.

ومع ذلك ، JAXBElement الكائنات حرج لبناء, منذ كنت في حاجة إلى تعرف عنصر XML اسم مساحة الاسم التي منطق الأعمال عادة لا.

الحمد لله, عندما XJC ينشئ فئة النموذج ، كما بإنشاء فئة تسمى ObjectFactory.هذا هو جزئيا هناك من أجل التوافق مع JAXB v1, لكنه أيضا هناك مكان XJC لوضع إنشاء مصنع الأساليب التي تخلق JAXBElement مغلفة حول الكائنات الخاصة بك.أنه يتعامل مع XML اسم مساحة الاسم بالنسبة لك, لذلك كنت لا داعي للقلق حول هذا الموضوع.تحتاج فقط أن ننظر من خلال ObjectFactory أساليب (الكبيرة المخطط ، يمكن أن يكون هناك مئات منهم) إلى العثور على واحد التي تحتاج إليها.

نصائح أخرى

وهذا مذكور في الجزء السفلي من بلوق وظيفة بالفعل مرتبطة أعلاه ولكن هذا يعمل مثل علاج بالنسبة لي:

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(new JAXBElement<MyClass>(new QName("uri","local"), MyClass.class, myClassInstance), System.out);

كما ألمح في واحدة من الإجابات أعلاه, لن XMLRootElement على عنصر الجذر إذا كان في XSD نوعه يعرف اسمه نوع ، منذ أن يدعى نوع يمكن استخدامها في أماكن أخرى في XSD.محاولة mking أنه مجهول النوع ، أيبدلا من:

<xsd:element name="myRootElement" type="MyRootElementType" />

<xsd:complexType name="MyRootElementType">
...
</xsd:complexType>

سيكون لديك:

<xsd:element name="myRootElement">
    <xsd:complexType>
    ...
    <xsd:complexType>
</xsd:element>

@XmlRootElement ليست هناك حاجة unmarshalling - إذا كان أحد يستخدم 2 المعلمة شكل Unmarshaller#unmarshall.

لذا ، إذا بدلا من القيام:

UserType user = (UserType) unmarshaller.unmarshal(new StringReader(responseString));

واحدة ينبغي أن تفعل:

JAXBElement<UserType> userElement = unmarshaller.unmarshal(someSource, UserType.class);
UserType user = userElement.getValue();

هذا الأخير رمز لا تتطلب @XmlRootElement الشرح في نوع المستخدم على مستوى الصف.

جو الجواب (جو يونيو 26 '09 الساعة 17:26) يفعل ذلك بالنسبة لي.الجواب بسيط هو أن غياب @XmlRootElement الشرح لا توجد مشكلة إذا كنت حشد JAXBElement.الشيء الذي أربكني هو إنشاء ObjectFactory 2 createMyRootElement طرق - الأولى لا يأخذ المعلمات ويعطي ملفوف الكائن الثاني يأخذ ملفوف موضوع يعود ملفوفة في JAXBElement ، التنظيم أن JAXBElement يعمل بشكل جيد.وهنا الأساسية قانون كنت (أنا جديدة على هذا لذا أعتذر إذا كان رمز ليس مهيأ بشكل صحيح في هذا الرد) إلى حد كبير من cribbed وصلة النص:

ObjectFactory objFactory = new ObjectFactory();
MyRootElement root = objFactory.createMyRootElement();
...
// Set root properties
...
if (!writeDocument(objFactory.createMyRootElement(root), output)) {
    System.err.println("Failed to marshal XML document");
}
...

private boolean writeDocument(JAXBElement document, OutputStream output) {

  Class<?> clazz = document.getValue().getClass();
  try {
    JAXBContext context =
        JAXBContext.newInstance(clazz.getPackage().getName());
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    m.marshal(document, output);
    return true;

  } catch (JAXBException e) {
    e.printStackTrace(System.err);
    return false;
  }
}

يمكنك إصلاح هذه المشكلة باستخدام الربط من كيفية توليد @XmlRootElement فصول قاعدة في أنواع XSD?.

هنا مثال مع مخضرم

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>1.3.1</version>
            <executions>
                <execution>
                    <id>xjc</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaDirectory>src/main/resources/xsd</schemaDirectory>
                <packageName>com.mycompany.schemas</packageName>
                <bindingFiles>bindings.xjb</bindingFiles>
                <extension>true</extension>
            </configuration>
        </plugin>

هنا binding.xjb محتوى الملف

<?xml version="1.0"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc"
              jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings schemaLocation="path/to/myschema.xsd" node="/xs:schema">
        <jxb:globalBindings>
            <xjc:simple/>
        </jxb:globalBindings>
    </jxb:bindings>
</jxb:bindings>

كما تعلمون الجواب هو استخدام ObjectFactory().هنا عينة من التعليمات البرمجية التي عملت بالنسبة لي :)

ObjectFactory myRootFactory = new ObjectFactory();

MyRootType myRootType = myRootFactory.createMyRootType();

try {

        File file = new File("./file.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(MyRoot.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

        //output pretty printed
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        JABXElement<MyRootType> myRootElement = myRootFactory.createMyRoot(myRootType);

        jaxbMarshaller.marshal(myRootElement, file);
        jaxbMarshaller.marshal(myRootElement, System.out);

    } catch (JAXBException e) {
        e.printStackTrace();
    }

إنه لا يعمل بالنسبة لنا أيضا.لكننا لم نجد على نطاق واسع-نقلت المقال أن يضيف بعض الخلفية...سوف تصل إلى هنا من أجل هذا الشخص التالي: http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html

في حالة تجربتي هذه المشكلة يعطي شخص يوريكا!لحظة..سأضيف التالية:

كنت أيضا الحصول على هذه المشكلة عند استخدام ملف xsd أن كنت قد تم إنشاؤها باستخدام IntelliJ هو "توليد xsd من الدرجة الوثيقة" خيار القائمة.

عندما قبول كافة الافتراضيات من هذه الأداة ، ولدت ملف xsd أنه عندما تستخدم مع jaxb, إنشاء ملفات جافا لا @XmlRootElement.في وقت عندما حاولت أن المشير لدي نفس الاستثناء كما نوقش في هذا السؤال.

عدت إلى IntellJ أداة ، ورأى الخيار الافتراضي في "Desgin نوع" المنسدلة (والتي بالطبع لم أفهم..و لا إذا أنا صادق) كان:

Desgin نوع:

"العناصر المحلية/العالمية أنواع معقدة"

لقد غيرت هذه

"العناصر المحلية/أنواع"

, الآن ولدت (إلى حد كبير) مختلفة xsd التي أنتجت @XmlRootElement عندما تستخدم مع jaxb.لا أستطيع القول أنني أفهم في والخروج منها ، لكنها عملت بالنسبة لي.

مع مخضرم بناء, يمكنك إضافة @XmlRootElement الشرح

مع "jaxb2-basics-annotate"في المكونات.

ترى المزيد من المعلومات :انظر

تكوين مخضرم لتوليد فصول من مخطط XML باستخدام JAXB

و JAXB XJC رمز جيل

هل حاولت تغيير إعدادات xsd مثل هذا ؟

<!-- create-logical-system -->
<xs:element name="methodCall">
  <xs:complexType>
    ...
  </xs:complexType>
</xs:element>

JAXBElement مغلفة يعمل في الحالات التي لا يوجد فيها @XmlRootElement تم إنشاؤه بواسطة JAXB.هذه الأغلفة المتوفرة في ObjectFactory الطبقة الناتجة عن maven-jaxb2-plugin.على سبيل المثال:

     public class HelloWorldEndpoint {
        @PayloadRoot(namespace = NAMESPACE_URI, localPart = "person")
        @ResponsePayload
        public JAXBElement<Greeting> sayHello(@RequestPayload JAXBElement<Person> request) {

        Person person = request.getValue();

        String greeting = "Hello " + person.getFirstName() + " " + person.getLastName() + "!";

        Greeting greet = new Greeting();
        greet.setGreeting(greeting);

        ObjectFactory factory = new ObjectFactory();
        JAXBElement<Greeting> response = factory.createGreeting(greet);
        return response;
      }
 }

بعد sruggling لمدة يومين وجدت الحل لهذه المشكلة.يمكنك استخدام ObjectFactory الطبقة إلى حل لهذه الفئات التي لا تملك @XmlRootElement.ObjectFactory وقد طاقتها طرق التفاف حول JAXBElement. الطريقة:1 لا مجرد إنشاء الكائن ، الطريقة:2 التفاف الكائن مع @JAXBElement.دائما استخدام الطريقة:2 لتجنب javax.xml.ربط.MarshalException - مع ربط الاستثناء في عداد المفقودين @XmlRootElement الشرح

الطريقة:1

public GetCountry createGetCountry() {
        return new GetCountry();
    }

الطريقة:2

 @XmlElementDecl(namespace = "my/name/space", name = "getCountry")
 public JAXBElement<GetCountry> createGetCountry(GetCountry value) {
        return new JAXBElement<GetCountry>(_GetCountry_QNAME, GetCountry.class, null, value);
    }

العمل نموذج التعليمات البرمجية:

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
WebServiceTemplate springWSTemplate = context.getBean(WebServiceTemplate.class);

GetCountry request = new GetCountry();
request.setGuid("1f3e1771-3049-49f5-95e6-dc3732c3227b");

JAXBElement<GetCountryResponse> jaxbResponse = (JAXBElement<GetCountryResponse>)springWSTemplate .marshalSendAndReceive(new ObjectFactory().createGetCountry(request));

GetCountryResponse response = jaxbResponse.getValue();

إلى soluction أنه يجب تكوين xml ملزم قبل أن تجمع مع wsimport ، ووضع generateElementProperty كاذبة.

     <jaxws:bindings wsdlLocation="LOCATION_OF_WSDL"
      xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
      xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
         <jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
    <jaxws:bindings  node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='NAMESPACE_OF_WSDL']">
      <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <xjc:generateElementProperty>false</xjc:generateElementProperty> 
      </jxb:globalBindings>
  </jaxws:bindings>
</jaxws:bindings>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top