java 无法将类型封送< CLASSNAME>为元素,因为它缺少@XmlRootElement注解

8fsztsew  于 2023-05-12  发布在  Java
关注(0)|答案(1)|浏览(182)

bounty还有2天到期。回答此问题可获得+250声望奖励。jarvo69想要引起更多关注这个问题:需要在至少java版本17上下文中回答这个问题和解决方案。
不重复,因为我已经尝试了很多解决方案,从stackoverflow像添加@XmlRootElement(name="Generic"),也试图 Package 的请求和响应对象在javax.xml.bind.JAXBElement,但没有任何工作,我到目前为止。编组/解组一直失败,它已经2天,因为我调试和挣扎与这个问题。

wsdl文件很大,所以这里只发布WSDL文件中的重要内容。
soap.wsdl

<types>
        <xs:schema xmlns:tns="http://www.oracle.com/UCM" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.oracle.com/UCM" version="1.0">
            <xs:element name="Field">
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="xs:string">
                            <xs:attribute name="name" type="xs:anySimpleType"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:element>
            <xs:element name="GenericRequest" type="tns:Generic"/>
            <xs:element name="GenericResponse" type="tns:Generic"/>
            <xs:complexType name="Generic">
                <xs:sequence>
                    <xs:element name="Service" type="tns:Service"/>
                </xs:sequence>
                <xs:attribute name="webKey" type="xs:anySimpleType"/>
            </xs:complexType>
            <xs:complexType name="Service">
                <xs:sequence>
                    <xs:element minOccurs="0" name="User" type="tns:Container"/>
                    <xs:element minOccurs="0" name="Document">
                        <xs:complexType>
                            <xs:complexContent>
                                <xs:extension base="tns:Container">
                                    <xs:sequence>
                                        <xs:element maxOccurs="unbounded" minOccurs="0" name="File" type="tns:File"/>
                                    </xs:sequence>
                                    <xs:anyAttribute namespace="##other" processContents="skip"/>
                                </xs:extension>
                            </xs:complexContent>
                        </xs:complexType>
                    </xs:element>
                </xs:sequence>
                <xs:attribute name="IdcService" type="xs:anySimpleType"/>
            </xs:complexType>
            <xs:complexType name="Container">
                <xs:sequence>
                    <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:Field"/>
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="ResultSet" type="tns:ResultSet"/>
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="OptionList" type="tns:OptionList"/>
                </xs:sequence>
                <xs:anyAttribute namespace="##other" processContents="skip"/>
            </xs:complexType>
            <xs:complexType name="ResultSet">
                <xs:sequence>
                    <xs:element maxOccurs="unbounded" minOccurs="0" name="Row" type="tns:Row"/>
                </xs:sequence>
                <xs:attribute name="name" type="xs:anySimpleType"/>
            </xs:complexType>
            <xs:complexType name="Row">
                <xs:sequence>
                    <xs:element maxOccurs="unbounded" ref="tns:Field"/>
                </xs:sequence>
                <xs:anyAttribute namespace="##other" processContents="skip"/>
            </xs:complexType>
            <xs:complexType name="OptionList">
                <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Option" type="xs:string"/>
                </xs:sequence>
                <xs:attribute name="name" type="xs:anySimpleType"/>
            </xs:complexType>
            <xs:complexType name="File">
                <xs:sequence>
                    <xs:element xmlns:ns1="http://www.w3.org/2005/05/xmlmime" name="Contents" ns1:expectedContentTypes="application/octet-stream" type="xs:base64Binary"/>
                </xs:sequence>
                <xs:attribute name="name" type="xs:anySimpleType"/>
                <xs:attribute name="href" type="xs:anySimpleType"/>
            </xs:complexType>
        </xs:schema>
    </types>
    <message name="GenericSoapOperationInput">
        <part name="GenericRequest" element="ns0:GenericRequest"/>
    </message>
    <message name="GenericSoapOperationOutput">
        <part name="GenericResponse" element="ns0:GenericResponse"/>
    </message>
    <portType name="GenericSoapPortType">
        <operation name="GenericSoapOperation">
            <input xmlns:ns1="http://www.w3.org/2006/05/addressing/wsdl" message="tns:GenericSoapOperationInput" ns1:Action="urn:GenericSoap/GenericSoapOperation"/>
            <output xmlns:ns1="http://www.w3.org/2006/05/addressing/wsdl" message="tns:GenericSoapOperationOutput" ns1:Action="urn:GenericSoap/GenericSoapPortType/GenericSoapOperationResponse"/>
        </operation>
    </portType>
    <binding name="GenericSoapPortTypeSoapHttp" type="tns:GenericSoapPortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#wss11_saml_or_username_token_with_message_protection_service_policy" wsdl:required="false"/>
        <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#wsmtom_policy" wsdl:required="false"/>
        <operation name="GenericSoapOperation">
            <soap:operation soapAction="urn:GenericSoap/GenericSoapOperation"/>
            <input>
                <soap:body use="literal" parts="GenericRequest"/>
                <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#GenericSoapPort_Input_Policy" wsdl:required="false"/>
            </input>
            <output>
                <soap:body use="literal" parts="GenericResponse"/>
                <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#GenericSoapPort_Output_Policy" wsdl:required="false"/>
            </output>
        </operation>
    </binding>
    <service name="GenericSoapService">
        <port name="GenericSoapPort" binding="tns:GenericSoapPortTypeSoapHttp">
            <soap:address location="https://myenvtest.oraclecloud.com:443/idcws/GenericSoapPort"/>
            <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
                <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">https://myenvtest.oraclecloud.com:443/idcws/GenericSoapPort</wsa:Address>
                
            </wsa:EndpointReference>
        </port>
    </service>

WSDL的Java配置类:

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

    @Bean
    public Jaxb2Marshaller jaxb2Marshaller() {
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setContextPath("com.example.camel.client.stub");
        jaxb2Marshaller.setMarshallerProperties(new HashMap<>() {{
            put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
        }});
        return jaxb2Marshaller;
    }

    @Bean
    public Marshaller marshaller() {
        return jaxb2Marshaller().createMarshaller();
    }

    @Bean
    public Unmarshaller unmarshaller() {
       return jaxb2Marshaller().createUnmarshaller();
    }

    @Bean
    public SoapClient soapClient(Jaxb2Marshaller marshaller) {
        SoapClient client = new SoapClient();
        client.setDefaultUri("https://myenvtest.oraclecloud.com:443/idcws/GenericSoapPort");
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        return client;
    }

下面是调用SOAP服务的SoapClient

SoapClient.java

public javax.xml.bind.JAXBElement<Generic> getGenericResponse() throws JAXBException {
        Generic request = new ObjectFactory().createGeneric();
        Service service = new ObjectFactory().createService();
        Service.Document document = new ObjectFactory().createServiceDocument();
        Field field = new ObjectFactory().createField();
        Container container = new ObjectFactory().createContainer();
        container.getField().add(field);
        service.setUser(container);
        field.setName("dID");
        field.setValue("2088250");
        document.getField().add(field);
        service.setIdcService("GET_FILE");
        service.setDocument(document);
        request.setService(service);
        request.setWebKey("cs");


       /* jakarta.xml.bind.Marshaller marshaller = jaxb2Marshaller.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(new JAXBElement<Generic>(new QName("http://www.oracle.com/UCM","GenericRequest"), Generic.class, request),
                System.out);

        String t = marshallXml(request);*/

        javax.xml.bind.JAXBElement<Generic> res = ( javax.xml.bind.JAXBElement<Generic>)
        getWebServiceTemplate().marshalSendAndReceive("https://myenvtest.oraclecloud.com/idcws/GenericSoapPort", request, new SoapActionCallback("https://myenvtest.oraclecloud.com/idcws/Generic"));
        
return null;
    }

我不断得到的错误是:

com.sun.istack.SAXException2: unable to marshal type "com.example.camel.client.stub.Generic" as an element because it is missing an @XmlRootElement annotation

泛型.java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.3.0 
// See <a href="https://javaee.github.io/jaxb-v2/">https://javaee.github.io/jaxb-v2/</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2023.05.06 at 09:42:41 AM IST 
//

package com.example.camel.client.stub;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;

/**
 * <p>Java class for Generic complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="Generic"&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="Service" type="{http://www.oracle.com/UCM}Service"/&gt;
 *       &lt;/sequence&gt;
 *       &lt;attribute name="webKey" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" /&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Generic", propOrder = {
    "service"
})
public class Generic {

    @XmlElement(name = "Service", required = true)
    protected Service service;
    @XmlAttribute(name = "webKey")
    @XmlSchemaType(name = "anySimpleType")
    protected String webKey;

    /**
     * Gets the value of the service property.
     * 
     * @return
     *     possible object is
     *     {@link Service }
     *     
     */
    public Service getService() {
        return service;
    }

    /**
     * Sets the value of the service property.
     * 
     * @param value
     *     allowed object is
     *     {@link Service }
     *     
     */
    public void setService(Service value) {
        this.service = value;
    }

    /**
     * Gets the value of the webKey property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getWebKey() {
        return webKey;
    }

    /**
     * Sets the value of the webKey property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setWebKey(String value) {
        this.webKey = value;
    }

}

注意:使用Java 18

idfiyjo8

idfiyjo81#

这个问题与以下事实有关:您正在尝试发送和接收作为顶级结构的complexTypeGeneric,而不是实际的element s,根据您的WSDL,它应该是:

<xs:element name="GenericRequest" type="tns:Generic"/>
<xs:element name="GenericResponse" type="tns:Generic"/>

理想情况下,您应该尝试修改SoapClient以使用GenericRequestGenericResponse的Java表示,而不是Generic(如果可能的话),更改应该是直接的。
但是,如果根据您的评论,您用于从WSDL文件生成类模型的Maven插件没有生成这些类,请尝试将Generic Package 在JAXBElement中,并将该对象传递给marshalSendAndReceive:我知道你在你的问题中提到了它,但请仔细检查你的代码,它应该工作。例如:

public javax.xml.bind.JAXBElement<GenericResponse> getGenericResponse() throws JAXBException {
  ObjectFactory factory = new ObjectFactory();
  Generic request = factory.createGeneric();
  Service service = factory.createService();
  Service.Document document = factory.createServiceDocument();
  Field field = factory.createField();
  Container container = factory.createContainer();
  container.getField().add(field);
  service.setUser(container);
  field.setName("dID");
  field.setValue("2088250");
  document.getField().add(field);
  service.setIdcService("GET_FILE");
  service.setDocument(document);
  request.setService(service);
  request.setWebKey("cs");

  /* jakarta.xml.bind.Marshaller marshaller = jaxb2Marshaller.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
  marshaller.marshal(new JAXBElement<Generic>(new QName("http://www.oracle.com/UCM","GenericRequest"), Generic.class, request),
    System.out);

  String t = marshallXml(request);*/

  // Note the following code, inspired by the code fragment above
  // The idea is wrap the Generic complexType in a JAXBElement
  JAXBElement<Generic> requestWrapper = 
    new JAXBElement<Generic>(
      new QName("http://www.oracle.com/UCM","GenericRequest"), 
      Generic.class, request);

  // Probably The generated `ObjectFactory` may contain a method
  // like the following for the same purpose:
  // JAXBElement<Generic> requestWrapper = createGenericRequest(request);

  javax.xml.bind.JAXBElement<GenericResponse> response = ( javax.xml.bind.JAXBElement<GenericResponse>)
        getWebServiceTemplate().marshalSendAndReceive(
    "https://myenvtest.oraclecloud.com/idcws/GenericSoapPort", 
    requestWrapper,
    new SoapActionCallback("https://myenvtest.oraclecloud.com/idcws/Generic"));
        
  return response;
}

类似的问题在SO in this或this other相关问题中也进行了修订。
This SO question解释了您所描述的JAXB生成器的行为。
这个other SO question也可能有帮助。

相关问题