Справочный интерфейс службы WCF и избыточные пространства имен в ответе веб-службы Java - PullRequest
0 голосов
/ 25 марта 2019

Итак, я работаю над внутренним проектом, в котором я использую веб-службу SOAP на основе Java из приложения WinForm, используя интерфейс справки службы WCF. (Это что-то новое для меня, поэтому я прошу прощения, если я не совсем использовал правильную терминологию и т. Д.) Я отправляю свой запрос в службу и получаю ответ, хотя для этого потребовалось некоторое количество прыжков. Формат ответа - это то, что вызывает у меня некоторые проблемы в том, что у него слишком много пространств имен, и размер ответа может стать большим.

Я надеюсь, что кто-то может подсказать мне простое решение / настройку, чтобы уменьшить избыток.

Несколько вещей, которые я не могу контролировать: Интерфейс через HTTP (не HTTPS), а безопасность обеспечивается с помощью механизма ключа / идентификатора приложения с использованием заголовка безопасности SOAP и клиентских сертификатов. WSDL-сервер не указывает, что WSSE требуется в заголовке SOAP, поэтому заголовок перезаписывается защитным заголовком перед отправкой.

Все элементы ниже являются фактической структурой кода и форматом запроса / ответа SOAP, но были изменены на общие элементы. Также «ответ» значительно уменьшается в размерах. При правильных параметрах запроса длина ответа превышает 64 КБ.

Пример запроса SoapUI 1, созданный с загрузкой WSDL, выглядит следующим образом:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pric="http://xmlns.example.com/system/pricing" xmlns:ns="http://xmlns.example.com/system/pricing/shared/3.1.1">
   <soapenv:Header/>
   <soapenv:Body>
      <pric: PricingRequest majorVersion="2" minorVersion="1">
         <pric:version>?</pric:version>
         <pric:timestamp>?</pric:timestamp>
         <!--1 or more repetitions:-->
         <pric:acctType>
            <!--You have a CHOICE of the next 2 items at this level-->
            <pric:customerNbr>?</pric: customerNbr >
            <pric:accountNbr>?</pric:accountNbr>
         </pric: acctType >
         <!--1 to 3 repetitions:-->
         <pric:system>?</pric: system >
         <pric:source>?</pric:source>
         <pric:searchItems>
            <pric:purchaseDate>?</pric: purchaseDate >
            <!--Zero or more repetitions:-->
            <pric:service>
               <ns:system>?</ns:system>
               <ns:serviceType>?</ns:serviceType>
               <!--Optional:-->
               <ns:serviceDesc>?</ns:serviceDesc>
               <!--Optional:-->
               <ns:billingType>?</ns:billingType>
               <!--Optional:-->
               <ns:effectiveDate>?</ns:effectiveDate>
               <!--Optional:-->
               <ns:expirationDate>?</ns:expirationDate>
               <!--Optional:-->
            </pric:service>
         </pric: searchItems >
      </pric: PricingRequest >
   </soapenv:Body>
</soapenv:Envelope>

Модель сервиса app.config - я добавил maxReceivedMessageSize для обработки больших ответов:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="PricingServiceSoap11" maxReceivedMessageSize="256000" />
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://pricing-websvc.example.com:60000/PricingService"
            binding="basicHttpBinding" bindingConfiguration="PricingServiceSoap11"
            contract="pricingSvcRef.PricingService" name="PricingServiceSoap11" />
    </client>
</system.serviceModel>

Код для использования сервиса:

pricingSvcRef.PricingClient pricing = new pricingSvcRef.PricingClient();

var reqInfo = new InspectorBehavior();
pricing.Endpoint.Behaviors.Add(reqInfo);

pricingSvcRef.PricingRequest request = new pricingSvcRef.PricingRequest();

request.majorVersion = 2;
request.minorVersion = 1;
request.version = pricingSvcRef.PricingRequestVersion.Ver1;
request.timestamp = DateTime.Now;

request.acctType = new pricingSvcRef.PricingRequestAcctType[1];
request.acctType[0] = new pricingSvcRef.GetPricingRequestAcctype();
request.acctType[0].Item = txtAcctNo.Text.Trim();

request.system = "Pricing";
request.source = "MyApp";

List<pricingSvcRef.pricingService> svcList = new List<pricingSvcRef.pricingService>();

svcList.Add(
        new pricingSvcRef.pricingService
        {
            system = txtSystem.Text.Trim(),
            serviceType = Convert.ToInt32(txServiceType.Text.Trim(),
            serviceDesc = txtService.Text.Trim(),
            billingType = Convert.ToInt32(txBillingType.Text.Trim(),
            effectiveDate = dateEffective.Value,
            expirationDate = dateExpiration.Value
        });

pricingSvcRef.PricingRequestSearchItems srchItems = new pricingSvcRef.PricingRequestSearchItems
{
    purchaseDate = DateTime.Now;
    service = svcList.ToArray(),
};

request.searchItems = srchItems;

pricingSvcRef.PricingResponse response = null;

try
{
    response = eddSvcRef.GetPricing(request);
}
catch (Exception ex)
{
    string msg = "Msg: " + ex.Message;

    if ((ex.InnerException != null) && (ex.InnerException.Message.Trim().Length > 0))
        msg = msg + "\r\n\r\nInner Msg: " + ex.InnerException.Message.Trim();

    MessageBox.Show(msg);
}

SOAP-запрос, который генерируется:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:Username>v1:APP1234567:SfPLRHKdXWWqW7mdOdk+gTABVo+y4VZR7UqLHWibVD73jaI0IL9FT4PMgAVAxGsa83P/aon61GuS+IZnuVjRHR4hJgyMuCvtI07QtNaSdwEyw9Lw/Iewm+098fkMYK2pflV7w6hn0U2A9/wzuQS/vfWe53vhGSX1zfhuo6AygKA=:APP1234567</wsse:Username>
      </wsse:UsernameToken>
    </Security>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <PricingRequest majorVersion="2" minorVersion="1" xmlns="http://xmlns.example.com/system/pricing">
      <version>1.0.0</version>
      <timestamp>2019-03-25T09:46:26.7337264-05:00</timestamp>
      <acctType>
        <accountNbr>123456789</accountNbr>
      </acctType>
      <system>Pricing</system>
      <source>MyApp</source>
      <searchItems>
        <purchaseDate>2019-03-25</purchaseDate>
        <service>
          <system xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">MyPricing</system>
          <serviceType xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">1000</serviceType>
          <serviceDesc xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">Service Description</serviceDesc>
          <billingType xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">1234</billingType>
          <effectiveDate xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">2019-01-01</effectiveDate>
          <expirationDate xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">2019-12-31</expirationDate>
        </service>
      </searchItems>
    </PricingRequest>
  </s:Body>
</s:Envelope>

SOAP Ответ в приложении:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header />
  <SOAP-ENV:Body>
    <PricingResponse xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1" xmlns:ns2="http://xmlns.example.com/system/pricing">
      <pricingContainer xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">
        <version xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">1.0.0</version>
        <timestamp xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">2019-03-25T14:46:28.876Z</timestamp>
        <source xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">MyApp</source>
        <status xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">
          <code xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">0000</code>
          <description xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">SUCCESS</description>
        </status>
        <acctType xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">
          <accountNbr xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">123456789</accountNbr>
        </acctType>
        <system xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">Pricing</system>
        <serviceDetail xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">
          <valid xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">Y</valid>
          <system xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">MyPricing</system>
          <serviceType xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">1000</serviceType>
          <serviceDesc xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">Service Description</serviceDesc>
          <billingType xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">1234</billingType>
          <effectiveDate xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">2019-01-01</effectiveDate>
          <expirationDate xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">2019-12-31</expirationDate>
          <pricingRate xmlns="http://xmlns.example.com/system/pricing/shared/3.1.1">100</pricingRate>
        </serviceDetail>
      </pricingContainer>
    </PricingResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Таким образом, хотя пространства имен возвращаются как часть элемента PricingResponse , они также присутствуют в каждом дочернем элементе ниже этого.

ОБНОВЛЕНИЕ: Я думал, что ответы SoapUI возвращаются без чрезмерного количества элементов пространства имен для каждого элемента, но теперь я определил, используя Wireshark и SoapUI Raw, что это не так.

Есть ли в любом случае запросить от интерфейса WCF к веб-службе Java, что ответ использует префиксы пространства имен, а не имеет пространство имен почти для каждого элемента ответа? Очевидно, что я собираюсь продолжать копаться в этом, но любая помощь / руководство будут оценены.

Спасибо

...