Нет @XmlRootElement, созданного JAXB - PullRequest
195 голосов
/ 04 мая 2009

Я пытаюсь сгенерировать Java-классы из FpML (Finanial Products 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]

На самом деле нет классов имеют аннотацию @XmlRootElement, так что я могу делать неправильно? Я указываю xjc (JAXB 2.1) на fpml-main-4-5.xsd, который включает все типы.

Ответы [ 14 ]

3 голосов
/ 09 августа 2017

Оболочки JAXBElement работают в случаях, когда JAXB не генерирует @XmlRootElement. Эти оболочки доступны в классе 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;
      }
 }
3 голосов
/ 03 мая 2011

Вы пытались изменить свой xsd следующим образом?

<!-- create-logical-system -->
<xs:element name="methodCall">
  <xs:complexType>
    ...
  </xs:complexType>
</xs:element>
2 голосов
/ 03 марта 2018

После двух дней работы я нашел решение проблемы. Вы можете использовать класс ObjectFactory , чтобы обойти классы, у которых нет @ XmlRootElement . ObjectFactory имеет перегруженные методы, чтобы обернуть его вокруг JAXBElement. Метод: 1 выполняет простое создание объекта, а Метод: 2 обернет объект с помощью @ JAXBElement . Всегда использовать Метод: 2 , чтобы избежать javax.xml.bind.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();
1 голос
/ 15 ноября 2011

Для решения этой проблемы вы должны сконфигурировать привязку xml, прежде чем компилировать с помощью wsimport, установив generateElementProperty как false.

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