【问题标题】:Java - Change SOAP Request Format using AXIS in Spring BootJava - 在 Spring Boot 中使用 AXIS 更改 SOAP 请求格式
【发布时间】:2018-11-20 16:21:18
【问题描述】:

我尝试在 Spring Boot 中使用 SOAP Web 服务。并使用 Axis 生成类。

我正在从客户端发送soap请求,它在去服务器时改变了请求的格式。

请找出客户端发送请求和服务器接收请求如下:

SOAP Client sending Request:

      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prim="http://..../..Services">
        <soapenv:Header />
        <soapenv:Body>
          <prim:UserList>
            <prim:XMLRequest>
              <prim:Header>
                <prim:MessageID>1</prim:MessageID>
                <prim:CorrelationID>1</CorrelationID>
              </prim:Header>
            </prim:XMLRequest>
          </prim:UserList>
        </soapenv:Body>
      </soapenv:Envelope>

SOAP Server receiving Request:

      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <soapenv:Body>
          <UserList xmlns="hhttp://..../..Services">
            <XMLRequest>
              <header>
                <MessageID>1</MessageID>
                <CorrelationID>1</CorrelationID>
              </header>
            </XMLRequest>
          </UserList>
        </soapenv:Body>
      </soapenv:Envelope>

尝试使用以下代码调用:

public  UserListResponse UserListService(UserList request)
            throws RemoteException, ServiceException {


        UserListRequest xmlRequest = new UserListRequest();

        Header reqHeader = request.getXMLRequest().getHeader();

        Header header = new Header();

        header.setCorrelationID(reqHeader.getCorrelationID());
        header.setMessageID(reqHeader.getMessageID());

        xmlRequest.setHeader(header);

        return soapStub.UserList(xmlRequest);

    }

Axis Serializer & deSerializer 代码如下:

// Type metadata
private static org.apache.axis.description.TypeDesc typeDesc =
    new org.apache.axis.description.TypeDesc(Header.class, true);

static {
    typeDesc.setXmlType(new javax.xml.namespace.QName("http://..../..Services", "Header","prim"));

    org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
    elemField.setFieldName("messageID");
    elemField.setXmlName(new javax.xml.namespace.QName("http://..../..Services", "MessageID","prim"));
    elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
    elemField.setMinOccurs(0);
    elemField.setNillable(false);
    typeDesc.addFieldDesc(elemField);
    elemField = new org.apache.axis.description.ElementDesc();
    elemField.setFieldName("correlationID");
    elemField.setXmlName(new javax.xml.namespace.QName("http://..../..Services", "CorrelationID","prim"));
    elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
    elemField.setMinOccurs(0);
    elemField.setNillable(false);
    typeDesc.addFieldDesc(elemField);


}

/**
 * Return type metadata object
 */
public static org.apache.axis.description.TypeDesc getTypeDesc() {
    return typeDesc;
}

/**
 * Get Custom Serializer
 */
public static org.apache.axis.encoding.Serializer getSerializer(
       java.lang.String mechType, 
       java.lang.Class _javaType,  
       javax.xml.namespace.QName _xmlType) {
    return 
      new  org.apache.axis.encoding.ser.BeanSerializer(
        _javaType, _xmlType, typeDesc);
}

/**
 * Get Custom Deserializer
 */
public static org.apache.axis.encoding.Deserializer getDeserializer(
       java.lang.String mechType, 
       java.lang.Class _javaType,  
       javax.xml.namespace.QName _xmlType) {
    return 
      new  org.apache.axis.encoding.ser.BeanDeserializer(
        _javaType, _xmlType, typeDesc);
}

谁能帮忙解决这个问题。

【问题讨论】:

  • 您需要提供有关您用于 Bean 到 XML 序列化的底层 API 的其他信息。

标签: java spring-boot soap axis soap-client


【解决方案1】:

我不确定,为什么你这么关心 XML 命名空间前缀的位置。

逻辑上的 XML A

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prim="http://..../..Services">... <prim:UserList>...</prim:UserList> </soapenv:Body> </soapenv:Envelope>

还有 XML B

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">... <UserList xmlns="hhttp://..../..Services"> </UserList> </soapenv:Body> </soapenv:Envelope>

您的用例是相同的。除了这里和那里的几个String字符之外没有什么区别。

在 XML A 的情况下,命名空间是在根级别定义的, 因此,孩子需要有本地名称前缀来识别(尽管如果没有冲突\相同的名称节点,可能会被跳过,这似乎是你的情况),它属于命名空间soapprim

在 XML B 的情况下,命名空间定义在parent node(UserList) 级别,因此可以避免所有子节点具有本地名称前缀。即Defining a default namespace for an element saves us from using prefixes in all the child elements.

我希望这能回答你的问题。

更多详情请参考XML Namespace

【讨论】:

  • 根据 xml 我同意你的看法。但是现有的 SOAP 服务不接受没有前缀的请求。那么有没有可能像在java中使用前缀一样创建与上面相同的请求。谢谢@Red Boy
  • 是的,有办法,但如果取决于您使用的库。如果您使用的是 JAXB,请查看它是否可以帮助您。 stackoverflow.com/questions/6895486/…
  • 不,我没有使用 JAXB,我使用轴从 wsdl 和轴生成类,使用序列化器和反序列化器来转换 xml,我已经更新了上面的代码。请对此进行检查并提供帮助。谢谢@Red Boy
  • 您必须修改 bean。像这样,public static final QName MY_QNAME = new QName("http://www.hello.com/Service/", "tagname", "prefix"); 参考stackoverflow.com/questions/74960/…
  • 因此需要为请求中的所有元素设置前缀,例如 elemField.setXmlName(new javax.xml.namespace.QName("http://..../..Services", “消息ID”,“prim”));。请确认。谢谢@Red Boy
猜你喜欢
  • 2017-05-16
  • 2015-11-15
  • 1970-01-01
  • 1970-01-01
  • 2020-05-20
  • 1970-01-01
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多