Driftschema för 1C-webbtjänsten. Webbservice. Tillhandahålla funktionalitet genom webbtjänster


Syftet med denna artikel– hjälpa till att förstå ”hur” WEB-tjänster är uppbyggda i 1C, förstå ”hur mekanismerna fungerar” och ”för vilka uppgifter” är det rationellt att använda dessa mekanismer.

Inslag i artikelnär det:

  • Olika metoder och tekniker som kan användas vid integration av 1C, WEB (php) och mobila (Ios, Android) applikationer övervägs (och jämförs med varandra);
U olika sätt har sina fördelar/nackdelar, och det är rationellt att välja den enklaste, kompakta för en specifik uppgift.
  • Samtidigt ges exempel på lösningar både på 1C-sidan och på WEB-serversidan (PHP);
Exempel på lösningar kan vara användbara för både 1C-programmerare och WEB-specialister, de som arbetar i skärningspunkten mellan områden.
  • All nödvändig information har samlats ihop ( steg för steg instruktioner) för att göra en "snabbstart" och börja utvecklingen. Det vill säga för att inte slösa mycket tid på att studera och konfigurera WEB-servrar, fönster, "fighting" systemfel etc.
Artikeln riktar sig till:
  • 1C: Programmerare och WEB-specialister som studerar integration med hjälp av webbtjänstteknik;
  • Designers och IT-analytiker måste förstå "essensen" och göra ett rationellt val av teknik när de skapar projekt.
Som avslutning på den inledande delen är det värt att säga att om du redan har erfarenhet av att arbeta med COM/Ole-teknologier, så kommer detta att hjälpa dig att förstå tekniken för WEB-tjänster.

1.1 Teknikkapacitet, stöd av 1C-plattformen

1.2 Tillämpning av teknologier för klient-server-interaktionsuppgifter.


2. Snabb start. Var ska man starta?


Punkt nr 0.
Först och främst måste du välja (bestämma) om integrationstekniken och förstå "essensen" - det vill säga hur det kommer att fungera.
Du måste med andra ord svara på två frågor:

  • Vilken 1C-databas (eller annat program) kommer att fungera som klient och vilken som server;
När du bestämmer vad som kommer att vara klienten och vad som kommer att vara servern kan du använda enkel regel: Klienten kan "ringa" (kontrollera) servern, men återuppringning är inte möjlig.
  • Vilken klient-server-interaktionsteknik som passar dig bäst och kommer att användas.
Jag beskrev mina rekommendationer för att välja teknik ovan.

Punkt nr 1.
Så, "essensen" av klient-server-interaktion förstås. Interaktionsteknik har fastställts. Nu behöver du skapa en "testplats" där utveckling kommer att ske.

I den här artikeln kommer två tekniker att diskuteras med hjälp av exempel:

Arbeta med mekanismen för WEB-tjänster.

Exempel på arbete från 1C 8 och PHP kommer att beaktas;

Arbeta med http-förfrågningsmekanismen (REST-webbtjänster).

Exempel på arbete från 1C 8 och PHP kommer också att beaktas;
I uppgifter relaterade till WEB-utveckling är det traditionellt accepterat:

  • Skapa en "testplats" för utveckling och felsökning på programmerarens lokala WEB-server (localhost);
  • Efter att utvecklingen är klar måste resultaten överföras till "combat" WEB-servern.

I praktiken (särskilt när du börjar "bekanta dig med" tekniken för WEB-tjänster), när du skapar en "testplats", såväl som när du överför ett projekt till en "kamp"-server, uppstår mycket "rake".

Så, för att inte "slösa" mycket tid på att "kämpa" med inställningarna IIS(Internet Information Server) / behärska servern apache och ställa in rättigheter Windows-åtkomst, jag rekommenderar följande:

  • (1) Skapa "Polygon" på din lokala arbetsmaskin. Operativsystem - Windows 7 (professionellt eller maximalt). Allt arbete ska utföras under konto administratör.
  • (2) Distribuera 1C 8-databasen i klient-serverläge (MS SQL-server, jag rekommenderar 2008 R2). Användning av 1C 8 i klient-serverläge kommer att eliminera behovet av att utföra ytterligare arbete. inställningar för åtkomsträttigheter till 1C-databasen från WEB-servern.
  • (3) Installera IIS, om det saknas. I Windows kan du "installera om" det regelbundet

Kryssrutorna för installationsalternativen för IIS-komponenter kan ställas in som standard.
De väsentliga sakerna du behöver vara uppmärksam på är följande alternativ (ISAPI-tillägg - detta behövs för att tvålanslutningar ska fungera i WEB-tjänster och CGI - detta krävs för att PHP ska fungera)

När installationen är klar IIS Låt oss se till att det fungerar. För detta, i adressfält Webbläsare ange:

(4) Publicera (ansluta) en 1C-databas på en WEB-server.

Och så, WEB-server IIS installerad och fungerar. Låt oss publicera vår 1C-databas och kontrollera att åtkomst till den nu också är möjlig via WEB-klienten.

Det är tillrådligt att publicera 1C-databasen på en WEB-server som tillhandahåller drift i ett hanterat applikationsläge (tunn klient).

Att publicera en 1C-databas görs så här:
I konfiguratorläget måste du anropa objektet "Publicera på en webbserver"

b) Ange publikationsparametrar:

Det vill säga i en katalog (mapp) wwwroot du är hans IIS du måste skapa en separat mapp (katalog) för publicering av din 1C-databas.

wwwrootkatalogen skapas automatiskt när IIS installeras
Låt oss skapa och välja en sådan mapp (wsBase10), ange namnet för publicering (vi kallar det också wsBase10).

Om du plötsligt får ett meddelande som svar,

var då inte rädd.

1C-publiceringsmekanismen är väldigt nyckfull. Försök att klicka på "Publicera" igen.

Och om du som ett resultat får ett meddelande,

det betyder att allt fungerade.

Det är mycket viktigt att förstå att när du publicerar en 1C-databas och dess WEB-tjänster på en "combat"-server (till exempel Windows 2008 R2), uppstår ofta fel om du bestämmer dig för att använda en webbserver IIS.

Råd: installera inte på en "combat"-server IIS! Installera apache.

Detta kommer att skydda dig från många systemfel. Och publicering (återpublicering - med ändringar i konfigurationen) kommer att ske för apache smidigt, utan att behöva mixtra med vrd-filer och inställningar IIS.

I den här artikeln kommer jag inte att överväga installationsprocessen och apache-inställningar. Det finns andra källor om detta ämne.

Dock för samarbete apache med 1C-databasen (och webbtjänster) finns det flera mycket viktiga krav som du behöver känna till (kom med detta till din systemadministratör).

1. Vid installation apache Se till att aktivera stöd för ISAPI-tillägg.

2. Aktivera cgi-bin-stöd om du kommer att arbeta med PHP;

3. Du måste ange en speciell "användare" i 1C-databasen...

Denna användare måste ha autentisering operativ system. Och du måste ange användaren under vars namn det lanseras apache.

... Vi är klara med apache och låt oss återvända till vår "Polygon" igen.

Här ser vi - 1C börjar. WEB-servern tillsammans med 1C fungerar.
4. Installera PHP-tjänsten för WINDOWS.

Du kommer att behöva det om du som en del av din uppgift behöver utveckla klient (webbsidor för åtkomst till 1C) eller server (scenarier för bearbetning av http-förfrågningar från 1C) i PHP.

5 Låt oss lägga till wsClient10-katalogen till IIS, där våra PHP-skript kommer att köras.

PHP-skript vi kommer att använda:

  • Att skapa klientdelen vid utveckling av 1C WEB-tjänster;
  • För utveckling av serverdelen, vid utveckling av REST webbtjänster (http-förfrågningar).

6. Låt oss installera programmet Notepap++. Denna kompakta och bekvämt program Jag rekommenderar att du använder den för att redigera PHP-skript.

Efter att ha installerat Notepad++ kontrollerar vi omedelbart att PHP fungerar för oss. Låt oss skapa ett enkelt hello.php-skript för detta. Låt oss placera det i wsClient-katalogen och köra skriptet från webbläsaren:

Allt ok. PHP fungerar. Testplatsen är helt klar.

3. Skapande av en WEB-tjänst, tvålförfrågningar, XDTO och JSON. Exempel 1C och PHP. I detta skede bör du ha "Polygon" redo och du kan börja utveckla WEB-tjänster.

– Var ska man börja studera den här tekniken? Naturligtvis med ett klassiskt problem som "Hej ord"!

1. Uppgiften att skapa det enklaste Webb-service. Låt oss titta på exempel i 1C och PHP.

1.1. Låt oss lägga till webbtjänsten "_Calculations by Tariffs" i ​​databasen (wsBase10)

Låt oss ställa in publiceringsfilens namn till "calcOrder10.1cws". URI-namnområdet måste också anges. I princip kan du ange vilket namn som helst.

1.2. Låt oss lägga till operationen "getHello" i webbtjänsten "_Calculations by Tariffs".

Essensen av operationen kommer att vara den enklaste - ta tre parametrar (strängar, siffror) som indata (från klienten) och returnera en förenande sträng tillbaka till honom (som ett resultat). Returvärdetypen kommer att vara primitiv - sträng.

Vi kommer inte att markera kryssrutan "I transaktion", eftersom operationen inte kommer att ändra data i själva 1C-databasen.

Om vår operation ändrade data i 1C-databasen skulle det vara meningsfullt att markera den här rutan.
Namnet på metoden (funktionen) som kommer att behandla inkommande data (och returnera resultatet) kommer att vara "getHello".

1.3. Låt oss lägga till inkommande parametrar för "getHello"-operationen.

Sändningsriktningen är "ingång". Det vill säga att de överförs från klienten till servern.

1.4. Låt oss skriva en hanterare för "getHello"-operationen i webbtjänstmodulen
///////////////////

Funktion getHello(strParametr, floatParametr, integerParametr)
return strParametr+string(floatParametr+integerParametr)
EndFunction

////////

1.5. Vid det här laget är arbetet med att skapa en enkel WEB-tjänst avslutat. Och nu måste du publicera WEB-tjänsten "_Calculations by Tariffs".

Innan vi publicerar en webbtjänst på testsidan kommer vi att ta bort alla användare från listan över användare av vår informationsbas. Det vill säga, vi kommer att göra listan över användare "tom".

- Varför göra det här?

På testplatsen kommer endast utvecklaren att kunna ansluta till WEB-tjänster, och därför är det ingen idé att tillhandahålla användarautentisering när man ansluter till WEB-tjänsten.

Det vill säga att vi medvetet kommer att förenkla vårt arbete med WEB-tjänster på testplatsen.

Vi behöver inte ange inloggning och lösenord när vi upprättar en anslutning.
Men på en "combat"-server måste du naturligtvis tillhandahålla autentisering.
För att göra detta (som nämndes tidigare), måste du separat skapa en användare i "combat"-databasen, på vars vägnar själva WEB-servern kommer att startas. Och sedan, när du upprättar en anslutning till WEB-tjänsten (tvålanslutning), måste du också ange användarens inloggning och lösenord.

1.6. Och så, låt oss publicera WEB-tjänsten:

Observera att vi inte behöver markera kryssrutan "Använd operativsystemautentisering på webbservern". Det beror på att detta läge tillhandahålls endast för WEB-server IIS, och på "combat"-servern kommer det att fungera Apache.

1.7. Låt oss skapa en klientdel och testa hur WEB-servern fungerar.

A) Låt oss först ringa ett kundsamtal från 1C.

Låt oss göra det helt enkelt. I någon annan 1C-databas som du har kommer vi att skapa extern bearbetning. I denna bearbetning kommer vi att ansluta till WEB-tjänsten, använda "getHello"-operationen, skicka parametrarna dit och få ett svar från servern.
Koden för "1C" blir ungefär så här:

/////

&OnClient
Procedur Execute Query10 (Command)
// Infoga innehållet i hanteraren.
LineResult = SERVER_ExecuteWSQuery10();
Varning(StringResult);
Slut på procedur
&PåServerUtan sammanhang
Funktion SERVER_RunWSRequest10()
// Vi kommer inte att utföra autentisering på testplatsen!
Användarnamn = odefinierat;
Lösenord = odefinierat;
http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ",Användarnamn,Lösenord);
Proxy.User = Användarnamn;
Proxy.Password = Odefinierat;
strResult = Proxy.getHello("Ivanov",100.35,20);
return strResult;
EndFunction ///////////////////////////////////////////////////////////////////////////////////////

Låt oss testa hur funktionen SERVER_ExecuteWSRequest10() fungerar.

OK. Arbetar!
b) Låt oss nu ringa klienten till webbtjänsten från PHP.
PHP-skriptkoden blir ungefär så här:

/
//////////////////////////////////////////////////////////////////////////////////

error_reporting(E_ERROR); // 1. Inaktivera onödiga meddelanden
// 2. Inaktivera cachning för SOAP. Om detta inte görs,


// 3. Upprätta en tvålkoppling
$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ",
array(
"login" => null, //login, vi kommer inte att utföra autentisering
"lösenord" => null, //lösenord
"spår" => sant,
"funktioner" => SOAP_USE_XSI_ARRAY_TYPE,
//"komprimering" =>
);
// 4. Fylla arrayen av godkända parametrar
$params["strParametr"] = "test_Soap10:";
$params["floatParametr"] = 10.34;
$params["integerParametr"] = 12;
// 5. Utför getHello-operationen
$result = $client->getHello($params);
// 6. Visa resultatet på skärmen
var_dump($resultat);
?>

////
///

Låt oss anropa skriptet från webbläsaren och kontrollera dess funktion:

Allt är bra, att ringa 1C från en webbsida fungerar!

Låt oss sammanfatta några resultat:
Problemet med en enkel WEB-tjänst är löst. Och nu kan du börja skapa mer komplexa WEB-tjänster.

Och komplikationen blir att vi (hittills) bara har opererat med primitiva datatyper. Naturligtvis kommer vi att behöva sända/ta emot objekt (aggregerad) datatyper också.

2. Uppgiften att skapa en WEB-tjänst med XDTO-paket.

Låt oss som tidigare titta på exempel i 1C och PHP.

Låt oss ställa följande uppgift: WEB-tjänsten bör inte returnera en sträng, utan objektdata - en "värdetabell" (mer exakt, det kommer att vara en uppsättning objekt!).

För att beskriva olika datastrukturer (som kommer att krävas vid mottagning/överföring till WEB-servern), tillhandahåller 1C:8-plattformen en mekanism för XDTO-paket.

De där. Först beskriver vi alla datatyper vi behöver, och sedan anger vi:

  • Vilka XDTO-paket kan vår WEB-tjänst arbeta med (du kan ange antingen ett eller en lista med paket);
  • För varje parameter för operationen och resultatet den returnerar kan du ange vilken typ av data (från XDTO-paketet) det kommer att vara.
Därefter kommer vi att titta på att arbeta med XDTO med exemplet att ta emot en viss "tarifftabell" från servern:

Låt oss skapa operationen GetTzTariffs_0, som returnerar data av typen tzTariffs.

Figuren visar att tzTariffer inkluderar ett obegränsat antal el-objekt. Faktum är att tzTariffer är en tabell över objekt av typen el.

- Hur ser man det?

  • Om parametern "maximal" anges som "-1", är antalet av dessa objekt inte begränsat (en tabell med ett obegränsat antal rader);
  • Om vi ​​inte behöver en tabell, utan bara behöver en struktur (en rad), bör de maximala och lägsta värdena anges lika med "1".
  • I sin tur är el-objektet en struktur som innehåller ett objekttypsattribut (eTariff) och ett primitivt typattribut (cPrice, kommentar).

När du rör dig nedåt i hierarkin kan du se att tarifftypen är en struktur (maximal och minsta kvantitet = 1), vars en av detaljerna inkluderar typen kindOfTariff.

Total: XDTO-paketet låter dig tydligt beskriva hierarkin av datatyper som kommer att användas vidare när du interagerar med en WEB-tjänst.

Tips: Det är bättre att använda ett XDTO-paket för en webbtjänst för att undvika komplexitet och undvika designfel.
Låt oss gå vidare... Efter:

  • XTDO-paketet har skapats;
  • Alla datatyper beskrivs;
  • För WEB-tjänsten anges användningen av detta paket;
  • För parametrar och resultat av operationer väljs lämpliga typer (från XDTO-paketet)
sedan kan du gå vidare till att "fylla" objekt (strukturer, arrayer av strukturer) med data.

I vårt exempel bör operationen GetTzTariffs_0 returnera en array av strängar som innehåller Tariffs-objekt.

////////////////

Funktion GetTzTariffs_0()
// Infoga innehållet i hanteraren.
Returnera GetTZTariffs_0();
EndFunction

Funktion GetTZTariffs_0()


// Fylla i de tekniska specifikationerna
// 1:a raden

kindOfTariff.active = falskt;


tariff.kind = kindOfTariff;

elementTZ.eTariff = tariff;
elementTZ.cPrice = 100;

//
// 2:a raden
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);

tariff = FactoryXDTO.Create(tariffType);
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
// Lägg till den andra raden i tabellen
tzTariffs.el.Add(elementTZ);
Retur tzTariffer;
EndFunction

//////////
Därefter ger vi ett exempel på att anropa operationen "GetTzTariffs_0" från klientsidan, från 1C.

&OnClient
Procedur Execute Query20 (Command)
// Infoga innehållet i hanteraren.
Varning(SERVER_ExecuteWSQuery20());
Slut på procedur
&PåServerUtan sammanhang
Funktion SERVER_ExecuteWSRequest20()
Definitioner = new WSDefinitions("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ");
Proxy = new WSProxy(Definitions,"www.URI.com","_Calculations By Tariffs","_Calculations By TariffsSoap");
XDTResult = Proxy.GetTzTariffs_0();
// Låt oss komma åt raden vid index noll, sedan till eTariff-attributet, sedan till den kapslade attributtypen och sedan till det kapslade attributnamnet.
EndFunction

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ett liknande anrop från PHP och bearbetning av XDTO-resultaten skulle se ut så här:
////////////////////////////////////////////////////////////////////////////////////



// webbtjänstens funktioner kommer inte att fungera korrekt.
ini_set("soap.wsdl_cache_enabled", "0");
$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ");
$result = $client->GetTzTariffs_0();
$mResult = $result->return->el;
// mResult - en array av objekt. Låt oss gå igenom elementen i arrayen och visa resultaten på skärmen
för ($i=0; $i {
eka"
";
$eTariff = iconv("utf-8","cp1251",$mResult[$i]->eTariff->fullständigt namn);
var_dump($eTariff);
$cPrice = $mResult[$i]->cPrice;
var_dump($cPrice);
$cComment = $mResult[$i]->cComment;
var_dump($cComment);
eka"
";
}
?>

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

Nu Låt oss komplicera uppgiften ännu mer. Låt oss överföra samma objektdatatyp från klienten till WEB-tjänsten (som en parameter). Låt det vara tzKind.
För att göra detta beskriver vi först denna typ i dataTariffs-paketet och lägger sedan till GetTzTariffs_1-operationen.

Låt oss ange typen av tzKind-parametern.

Ett exempel på hur en WEB-tjänst fungerar med en inkommande XDTO-parameter:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Funktion GetTZTariffs_1(tzKind)
tzTariffsType = FactoryXDTO.Type(" ", "tzTariffs");
tzTariffs = FactoryXDTO.Create(tzTariffsType);
elementTZType = FactoryXDTO.Type(" ", "elementTZ");
tariffType = FactoryXDTO.Type(" ", "tariff");
kindOfTariffType = FactoryXDTO.Type(" ", "kindOfTariff");
// Fylla i de tekniska specifikationerna
// 1:a raden
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);
kindOfTariff.name = "Transport";
kindOfTariff.active = falskt;
tariff = FactoryXDTO.Create(tariffType);
tariff.fullName = "Taxa 1";
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 100;
elementTZ.comment = "Beskrivning av taxa 1";
// Lägg till den första raden i tabellen
tzTariffs.el.Add(elementTZ);
// 2:a raden
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);
kindOfTariff.name = "Leverans";
kindOfTariff.active = sant;
tariff = FactoryXDTO.Create(tariffType);
tariff.fullName = "Taxa 2";
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
elementTZ.comment = "Beskrivning av taxa 2";
// Lägg till en tredje rad i tabellen (fyll den med inkommande data)
tzTariffs.el.Add(elementTZ);
// 3:e raden
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);
kindOfTariff.name = tzKind.el.eKind.name;
kindOfTariff.active = tzKind.el.eKind.active;
tariff = FactoryXDTO.Create(tariffType);
tariff.fullName = "Taxa 3";
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 300;
elementTZ.comment = "Beskrivning av taxa 3";
// Lägg till en tredje rad i tabellen
tzTariffs.el.Add(elementTZ);
Retur tzTariffer;
EndFunction

//////////////////////////////////////////////////////////////////////////////////
Från 1C-klientsidan kommer vi att behöva förbereda data av typen tzKind och överföra dem till WEB-tjänsten.

Här är ett exempel på ett sådant samtal:
/////////////////////////////////////////////////////////////////////////////////

&OnClient
Procedur Kör Query30 (kommando)
// Infoga innehållet i hanteraren.
Varning(SERVER_ExecuteWSQuery30());
Slut på procedur
&PåServerUtan sammanhang
Funktion SERVER_ExecuteWSRequest30()
Definitioner = new WSDefinitions("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ");
Proxy = new WSProxy(Definitions,"www.URI.com","_Calculations By Tariffs","_Calculations By TariffsSoap");
// Skapa en tabell med parametrar som skickas till WS
tzKindType = Proxy.FactoryXDTO.Type(" ", "tzKind");
tzKind = Proxy.FactoryXDTO.Create(tzKindType);
kindOfTariffType = Proxy.FactoryXDTO.Type(" ", "kindOfTariff");
kindOfTariff = Proxy.XDTO Factory.Create(kindOfTariffType);
kindOfTariff.name = "Testtarifftyp";
kindOfTariff.active = falskt;
elementKindType = Proxy.FactoryXDTO.Type(" ", "elementKind");
elementKind = Proxy.XDTO Factory.Create(elementKindType);
elementKind.eKind = kindOfTariff;
elementKind.qty = 10;
// Lägg till en rad i tabellen
tzKind.el.Add(elementKind);
XDTOResult = Proxy.GetTzTzriffs_1(tzKind);
ExempelResult_Name of Tariff Type = XDTOResult.el.eTariff.kind.name;
Returnera ExempelResult_Name of Tariff Type;
EndFunction

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Jag skulle vilja fästa din uppmärksamhet på designen: Proxy.FactoryXDTO.Type("...

Det vill säga när vi skapar ett XDTO-paketobjekt på klienten måste vi inte komma åt vår egen XDTO!-fabrik utan genom en proxy. Det vill säga till XDTO-serverfabriken.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Nu är det dags att ställa frågan:finns det något alternativ till XDTO-objekt ?

Är det möjligt att "inte kommunicera" med XDTO-fabriken överhuvudtaget, sända/ta emot från en WEB-tjänst på något annat sätt.. (speciellt om klienten inte är 1C, utan till exempel en WEB-sida, en applikation på Android, iOS , etc.).

Svaret är- Jo det kan du!
Du kan till exempel använda sträng som parametertyper. Och "packa" (serialisera) datastrukturer i den.

Denna teknik inom WEB-programmering har länge utvecklats och kallas JSON.
Det är också en stor hjälp att i PHP, packning/extrahering av alla strukturer/arraysträngar görs i ett steg!
Ett exempel i PHP på att paketera objekt i JSON/extrahera, sända/ta emot till en WEB-tjänst:

///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////

// serialisera mDelivery-arrayen till en sträng och placera den i leveransparametern
// * Låt oss först beskriva leveransstrukturen
klass leverans(
var $id;
var $checked;
var $värde;
}
// Fyll strukturen med lite data
$sDelivery = ny leverans;
$sDelivery->id = "000000005";
$sDelivery->checked = TRUE;
$sDelivery->value = 0;
// Lägg till den i arrayen av mDelivery-objekt
$mDelivery = $sDelivery;
// Konvertera mDelivery-arrayen till en JSON-sträng och placera resultatet i leveransparametern
$params["delivery"] = json_encode($mDelivery);
// Anropa ExitCalcOrder-operationen på WEB-tjänsten och skicka en parameter till den (sträng - leverans);
$result = $client->ExitCalcOrder($params);
// Hämta resultatet av ExitCalcOrder-operationen till variabeln jsCalcResult (sträng)
$jsCalcResult = $result->retur;
// Utför den omvända transformationen: från jsCalcResult-strängen till ett objekt (en array av objekt, typ matchning) arrCalcResult
$arrCalcResult = json_decode($jsCalcResult);
// Visa information på skärmen om objektet arrCalcResult
var_dump($arrCalcResult);

////////////////////////////////////////////////////////////////////////////////

Men hur utför man JSON-konverteringar i 1C?
1C 8-plattformen stöder inte JSON-standarden, men detta är inget problem.
JSON-konverterings-/extraktionsbehandling finns, är tillgänglig och fungerar utmärkt från
// Copyright © 2010-2012 Alexander Pereverzev
// 1C:JSON . JavaScript Object Notation parser och serializer.

Lägg därför bara in denna bearbetning i din konfiguration så kan du enkelt utföra framåt- och bakåt-JSON-konverteringar:
Serialiseringsexempel 1C-objekt till JSON-strängen:

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

CargoData = ny struktur;
CargoData.Insert("kod", CargoCode);
CargoData.Insert("nummer", CargoNumber);
CargoData.Insert("plan", QuantityPlan);
CargoData.Insert("character",CargoCharacter);
CargoData.Insert("packing", Packaging);
CargoData.Insert("skada",Skada på förpackning);
CargoData.Insert("volym",Volym);
CargoData.Insert("weight",Weight);
CargoData.Insert("status",Status);
jsResult = JSON.WriteJSON(LoadData); //Konvertera resultatet till JSON
returnera jsResult;

Extrahera exempel objekt i 1C från JSON-strängen:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1. Återställ objekt från JSON
JSON = Process.JSON.Create();
mdelivery = JSON.ReadJSON(leverans);
// som ett resultat är mdelivery en array. Arrayelement - matcha.
// Det är till exempel mdelivery.["id"] kommer att innehålla "000000005"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Avslutningsvis kommer jag att ge ett exempel på att anropa 1C-webbtjänsten från PHP och ta emot den returnerade JSON-strukturen av dess omvända transformation till PHP-objekt.

Låt oss vara uppmärksamma på omvandlingarna iconv("cp1251","utf-8","
och iconv("utf-8","cp1251", som kommer att krävas (när man interagerar med PHP - 1 C) för att konvertera kyrilliska strängar från cp 1251-kodning till utf -8 och tillbaka.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

error_reporting(E_ERROR); // Inaktivera meddelanden
// Inaktivera cachning för SOAP. Om detta inte görs,
// webbtjänstens funktioner kommer inte att fungera korrekt.
ini_set("soap.wsdl_cache_enabled", "0");
$client = new SoapClient("http://localhost/wsBase10/ws/wsQuery.1cws?wsdl ");
$params["fname"] = iconv("cp1251","utf-8","dataFreight");
$params["param1"] = iconv("cp1251","utf-8",$_GET["kod"]);
$params["param2"] = iconv("cp1251","utf-8",$_GET["nummer"]);
$result = $client->executeQuery($params);
$jsResult = $result->retur;
$dataFreight = json_decode($jsResult);
$statusFreight = $dataFreight->codeNm;
$numberFreight = iconv("utf-8","cp1251",$dataFreight->nameRus);
?>

///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////

Det troliga scenariot är: en fjärranvändare från några av sina program (till exempel från en WEB-sida, mobilapplikation, etc.) ringer din WEB-tjänst och... får inga resultat.. Eller så får han det, men något är fel.

Fråga: - Hur får man reda på sådana fel och felsöker WEB-tjänsten?
Jag rekommenderar att du använder en logg för att övervaka fel (och samla in inkommande parametrar "vad som ledde webbtjänsten till ett fel").

De där. på den plats där logiska fel kan uppstå, spara programinformation om inkommande parametrar i registreringsloggen (LogRecord)

Om du "kämpar" med "runtime errors" kan du fånga upp dem (ett försök är ett undantag) och "punkt för punkt" logga hela situationen.

Som ett resultat, med hjälp av loggen, kommer du att kunna se information om fel, reproducera parametrarna för händelsen och "besegra" den i interaktivt läge, i felsökaren.

Låt oss sammanfatta: Exempel på att arbeta med WEB-tjänster från 1C och PHP beaktas. För att överföra objektdatastrukturer mellan klienten och servern använde vi två tekniker:

  • (1) XDTO-paket
  • (2) JSON-objekt.

4. Alternativ - REST webbtjänster (http-förfrågningar). Exempel på implementering i 1C och PHP.
I föregående avsnitt undersökte vi i detalj tekniken för WEB-tjänster. I detta avsnitt kommer vi att överväga en alternativ teknik, den så kallade. REST webbtjänster.

En rättvis fråga uppstår: - Varför?

WEB-tjänster är fullt funktionella och låter dig lösa problem av vilken komplexitet som helst.

För att förstå "varför", låt oss formulera de grundläggande skillnaderna mellan dessa teknologier.

Tekniken för WEB-tjänster är baserad på 2 punkter:

  • (1) SOAP-anslutning används. Med andra ord görs en SOAP-förfrågan.
I "1C" tvål bildas anslutningen enligt följande:
/////////////////////////////////////////////////////////////////////////////////////////

Definitioner = new WSDefinitions("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",Användarnamn,Lösenord);
Proxy = new WSProxy(Definitions,"www.URI.com","_Calculations By Tariffs","_Calculations By TariffsSoap");

/////////////////////////////////////////////////////////////////////////////////////////

I PHP är det så här:

/////////////////////////////////////////////////////////////////////////////////////////

$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ",
array(
"login" => inloggning, //login,
"lösenord" => pass, //lösenord
"spår" => sant,
"funktioner" => SOAP_USE_XSI_ARRAY_TYPE,
//"komprimering" => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5
);

/////////////////////////////////////////////////////////////////////////////////////////

  • (2) För att bearbeta en tvålkoppling i serverläge tillhandahåller 1C 8-plattformen ett speciellt metadataobjekt WEB-tjänster.

Dessutom, om "1C" i din uppgift måste fungera som en server, så finns det inget alternativ till 1C WEB-tjänstteknik.

– När är ett alternativ möjligt?

  • För det första, när 1C endast agerar som kund;
  • För det andra, när servern du behöver arbeta med (till exempel en webbplats eller någon form av WEB-applikation), är det inte planerat att stödja en SOAP-anslutning.
- Vilket alternativ till en SOAP-anslutning är möjligt?

Ett mycket populärt alternativ - http-anslutning.

I webbaserade system (PHP, Android, iOS) är det lättare att arbeta med http-förfrågningar än med SOAP-förfrågningar. Och för inte särskilt komplexa projekt är http-förfrågningstekniken ganska lämplig.

Den klassiska lösningen (med http-förfrågningsmetoden) är uppgiften att integrera 1C-databasen och webbsidan. Till exempel skickas information om sortiment och priser till webbplatsen och information om accepterade beställningar skickas tillbaka från webbplatsen.

Det är typiskt att i typiska 1C-konfigurationer implementeras integration med webbplatser med hjälp av http-förfrågningar.
Så låt oss titta på tekniken http-förfrågningar Till exempel interaktion mellan 1C (klient, 1C 8) och WEB-plats (PHP, server).

1. Etablera en anslutning och metoder för att skicka parametrar i en http-förfrågan

Ett exempel på att upprätta en anslutning till servern från 1C-sidan:
/////////////////////////////////////////////////////////////////////////////

skyddad = falsk;
HTTPConnect = new HTTPConnect("localhost/wsClient10/json/testHTTPQuery11.php", skyddad);

////////////////////////////////////////////////////////////////////////////
Som du vet finns det två metoder för att överföra parametrar från klienten till servern via http-protokollet:

(1) Metod "get";

Parametrar (som namn och lösenord) anges direkt i serveranropets URL.

Det vill säga, ett interaktivt anrop till skriptet (direkt från en webbläsare) skulle se ut så här:

I 1C:8, för att programmässigt anropa servern (och skicka parametrar för Get-metoder till den), tillhandahålls "Get"-metoden.

Exempel:
skyddad = falsk;
HTTPConnect = new HTTPConnect("localhost", Säker);
HTTPConnect.Get("wsClient10/json/testHTTPQuery11.php?nameVasya&password=123",OutputFileName);

where OutputFileName: Namnet på filen som data som returneras från servern placeras i.
Det vill säga, som ett resultat av att bearbeta begäran, returnerar servern resultatet till 1C och sedan (automatiskt) genereras en fil som innehåller resultatet.

Följaktligen, efter detta, i "1C" är det nödvändigt (programmässigt) att läsa den här filen och extrahera resultatet från den. Det är allt.

(2) "post"-metod;

I det här alternativet placeras inte parametrarna i URL:en, utan överförs separat i http-anslutningens brödtext.

Det är tydligt att den viktigaste begränsningen av metoden skaffa sigär volymen och innehållet i de överförda data. Det vill säga med hjälp skaffa sig Endast tecken kan skickas och längden på URL-strängen är begränsad.

Metod posta Du kan överföra data av olika innehåll, inkl. och godtyckliga filer.
Således, posta för integrationsuppgifter är den mer funktionell och vi kommer att fortsätta arbeta med den.

För att ta emot/sända data mellan 1C och WEB-sidan kommer vi att använda textfiler.
Och vi kommer att "packa/extrahera" data från filer med JSON-tekniken som redan är bekant för oss! Detta kommer praktiskt taget att rädda oss från behovet av att "tolka" filen på 1C-sidan och på PHP-sidan.

För att anropa servern och överföra parametrar till den med "post"-metoden, tillhandahåller 1C:8 metoden: SendForProcessing

Och så, låt oss ge ett exempel där på sidan 1C alla bearbetningssteg utförs http-förfrågan:

Låt oss först skriva ner handlingsplanen (förstorad):

Och nu, dess mjukvaruimplementering i 1C:8

////////////////////

// 1. Fyll i strukturen för de överförda uppgifterna
postDataToPHP = ny struktur;
postDataToPHP.Insert("param1","ivanon");
postDataToPHP.Insert("param2","ivan");
postDataToPHP.Insert("param3","ivanovich");

// 2. Konvertera data till en JSON-sträng
JSON = Process.JSON.Create();
jsPostDataToPHP = JSON.WriteJSON(postDataToPHP);


// 3. Skapa ett tillfälligt utgående meddelande (sänds till servern med POST-metoden)
// fil, lägg en JSON-sträng i den.
tFile = nytt TextDocument;
stringData = jsPostDataToPHP;
tFile.AddLine(stringData);


// 4. Hämta namnet på den temporära utgående filen. Den kommer att innehålla utgående data i form av en JSON-sträng
OutgoingFileName = GetTemporaryFileName(.txt");

tFile.Write(OutgoingFileName,TextEncoding.UTF);

// 5. Hämta namnet på den temporära indatafilen. Den kommer att få en JSON-sträng: PHP-serversvar
InputFileName = GetTemporaryFileName(.txt");


// 6. Upprätta en HTTP-anslutning med servern
skyddad = falsk;
HTTPConnect = new HTTPConnect("localhost/wsClient10/json/testHTTPQuery10.php", skyddad);


// 7. Låt oss köra en HTTP-förfrågan. Låt oss överföra den utgående filen till servern (filen innehåller ett JSON-objekt, d.v.s. utgående parametrar)


HTTPConnect.SendForProcessing(OutgoingFileName,"/json/",IncomingFileName);


// Och vi kommer att få ett svar från servern (inkommande fil). Filen innehåller ett //JSON-objekt (dvs data som returneras från servern)

// 8. Extrahera data som tas emot från servern från den inkommande filen
ResponseFile = nytt TextDocument;
ResponseFile.Read(InputFileName,TextEncoding.UTF);
json_Data = ResponseFile.GetString(1);
mData = JSON.ReadJSON(json_Data);


// 9. Visa mottagen data för användaren
Report(mData["v1"]);
Report(mData["v2"]);


// 10. Ta bort använda (behövs inte längre) temporära filer.
DeleteFiles(OutgoingFileName);
DeleteFiles(InputFileName);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Och slutligen, exempel i PHP för att bearbeta en begäran på serversidan:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1. Hämta strängdata från den inkommande filen
$json_filedata = file_get_contents("php://input");
// 2. Klipp bort allt onödigt (2 tjänstecken läggs till), som // stör konverteringen från JSON
$jsData = trim(ltrim($json_filedata));
$dlinaStr = strlen($jsData);
$_jsData = "";
$i=1;
medan ($i<$dlinaStr) {
om ($i>2) (
$_jsData = $_jsData.substr($jsData, $i, 1);
}
$i++;
}
// 3. Konvertera data från JSON till ett objekt (struktur)
$mData = json_decode($_jsData);
// 4. Låt oss skapa en annan struktur, som vi fyller med data och // återgår till 1C
klass returnData(
var $v1;
var $v2;
}
$sReturnData = ny returData;
$sReturnData->v1 = $mData->param1;
$sReturnData->v2 = $mData->param2;
// 5. Konvertera strukturdata till en JSON-sträng
$json_returnData = json_encode($sReturnData);
// 6. Returnera data till 1C (utdata kommer att omdirigeras till en fil, som kommer att returneras till 1C)
echo $json_returnData;
?>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Det är allt. Kompakt och funktionell!

5. Efterfrågade uppgifter (projektärenden)

Avslutningsvis kommer jag att citera de som de facto nu är mest efterfrågade av kunderna, och som löses med hjälp av WEB-tjänster och http-förfrågningar.

Ämnets rubrik är verkligen en fråga, för... Jag vet inte själv vad det är och för första gången ska jag försöka arbeta med det inom ramen för denna artikel. Det enda jag kan garantera är att koden som presenteras nedan kommer att fungera, men mina fraser kommer bara att vara antaganden och gissningar om hur jag själv förstår allt detta. Låt oss gå...

Introduktion

Vi måste börja med varför konceptet webbtjänster skapades. När detta koncept dök upp i världen fanns det redan teknologier som gjorde det möjligt för applikationer att interagera på avstånd, där ett program kunde anropa någon metod i ett annat program, som kunde startas på en dator i en annan stad eller till och med ett land. Allt detta förkortas RPC (Remote Procedure Calling). Exempel inkluderar CORBA-teknologier och för Java - RMI (Remote Method Invoking). Och allt verkar vara bra i dem, speciellt i CORBA, för... Du kan arbeta med det i vilket programmeringsspråk som helst, men något saknades fortfarande. Jag tror att nackdelen med CORBA är att den fungerar genom några av sina egna nätverksprotokoll istället för enkla HTTP, som passar genom vilken brandvägg som helst. Tanken med webbtjänsten var att skapa en RPC som skulle infogas i HTTP-paket. Därmed började utvecklingen av standarden. Vilka är de grundläggande begreppen i denna standard:
  1. TVÅL. Innan du anropar en fjärrprocedur måste du beskriva detta samtal i en XML-fil i SOAP-format. SOAP är helt enkelt en av de många XML-uppmärkningar som används i webbtjänster. Allt vi vill skicka någonstans via HTTP konverteras först till en XML SOAP-beskrivning, stoppas sedan i ett HTTP-paket och skickas till en annan dator i nätverket via TCP/IP.
  2. WSDL. Det finns en webbtjänst, d.v.s. ett program vars metoder kan anropas på distans. Men standarden kräver att det här programmet åtföljs av en beskrivning som säger att "ja, du har rätt - det här är verkligen en webbtjänst och du kan anropa sådana och sådana metoder från den." Denna beskrivning representeras av en annan XML-fil, som har ett annat format, nämligen WSDL. De där. WSDL är bara en XML-fil som beskriver en webbtjänst och inget mer.
Varför så kortfattat frågar du? Kan du inte vara mer specifik? Det är förmodligen möjligt, men för att göra detta måste du vända dig till böcker som T. Mashnin, "Java Web Services". Där, under de första 200 sidorna, finns en detaljerad beskrivning av varje tagg i SOAP- och WSDL-standarderna. Är det värt att göra? Enligt min åsikt nej, för... allt detta skapas automatiskt i Java, och du behöver bara skriva innehållet i de metoder som är tänkta att kallas på distans. Så ett API som JAX-RPC dök upp i Java. Om någon inte vet, när de säger att Java har ett sådant och ett API, betyder det att det finns ett paket med en uppsättning klasser som kapslar in den aktuella tekniken. JAX-RPC utvecklades med tiden från version till version och blev så småningom JAX-WS. WS står uppenbarligen för WebService och du kanske tror att detta helt enkelt är ett byte av RPC som ett populärt modeord nuförtiden. Detta är inte sant, eftersom Nu har webbtjänster gått bort från den ursprungliga idén och låter dig inte bara anropa fjärrmetoder, utan också att helt enkelt skicka dokumentmeddelanden i SOAP-format. Jag vet inte varför detta behövs ännu; det är osannolikt att svaret här kommer att vara "ifall det behövs." Själv skulle jag vilja lära mig av mer erfarna kamrater. Och sist, då dök JAX-RS upp för så kallade RESTful webbtjänster, men detta är ämnet för en separat artikel. Introduktionen kan sluta här, eftersom... Därefter ska vi lära oss att arbeta med JAX-WS.

Allmän riktlinje

I webbtjänster finns det alltid en klient och en server. Servern är vår webbtjänst och kallas ibland för slutpunkten (som i slutpunkten dit SOAP-meddelanden från klienten når). Vi behöver göra följande:
  1. Beskriv gränssnittet för vår webbtjänst
  2. Implementera detta gränssnitt
  3. Starta vår webbtjänst
  4. Skriv en klient och fjärranrop önskad webbtjänstmetod
Du kan starta en webbtjänst på olika sätt: antingen beskriva en klass med huvudmetoden och starta webbtjänsten direkt som en server, eller distribuera den till en server som Tomcat eller någon annan. I det andra fallet startar vi inte själva en ny server och öppnar inte en annan port på datorn, utan säger helt enkelt till Tomcat servletcontainern att ”vi har skrivit webbtjänstklasser här, vänligen publicera dem så att alla som kontaktar dig kan använd vår användning av webbtjänsten." Oavsett sätt att lansera webbtjänsten kommer vi att ha samma klient.

Server

Låt oss lansera IDEA och skapa ett nytt projekt Skapa nytt projekt. Låt oss ange namnet Hej WebService och tryck på knappen Nästa, sedan knappen Avsluta. I mapp src låt oss skapa ett paket ru.javarush.ws. I det här paketet kommer vi att skapa HelloWebService-gränssnittet: package ru. javarush. ws; // dessa är anteckningar, dvs. ett sätt att markera våra klasser och metoder, // relaterat till webbtjänstteknik importera javax. jws. WebMethod; importera javax. jws. Webb-service; importera javax. jws. tvål. SOAPBindning; // vi säger att vårt gränssnitt kommer att fungera som en webbtjänst@Webb-service // vi säger att webbtjänsten kommer att användas för att anropa metoder@SOAPBinding (stil = SOAPBinding. Style. RPC) offentligt gränssnitt HelloWebService ( // vi säger att denna metod kan kallas på distans@WebMethod public String getHelloString(String name) ; ) I den här koden är klasserna WebService och WebMethod så kallade annoteringar och gör ingenting förutom att markera vårt gränssnitt och dess metod som en webbtjänst. Detsamma gäller för SOAPBinding-klassen. Den enda skillnaden är att SOAPBinding är en annotering med parametrar. I det här fallet används stilparametern med ett värde som indikerar att webbtjänsten inte kommer att fungera genom dokumentmeddelanden, utan som en klassisk RPC, d.v.s. att anropa en metod. Låt oss implementera vår gränssnittslogik och skapa en HelloWebServiceImpl-klass i vårt paket. Förresten, jag noterar att att avsluta en klass med Impl är en konvention i Java, enligt vilken implementeringen av gränssnitt är så betecknad (Impl - från ordet implementering, dvs implementering). Detta är inget krav och du är fri att benämna klassen vad du vill, men gott uppförande kräver det: paket ru. javarush. ws; // samma anteckning som när man beskriver gränssnittet, importera javax. jws. Webb-service; // men här används den med parametern endpointInterface, // som anger det fullständiga namnet på gränssnittsklassen för vår webbtjänst@WebService(endpointInterface= "ru.javarush.ws.HelloWebService") public class HelloWebServiceImpl implementerar HelloWebService ( @Override public String getHelloString (String name) ( // returnera bara hälsningen returnera "Hej, " + namn + "!" ; ) ) Låt oss lansera vår webbtjänst som en oberoende server, d.v.s. utan deltagande av någon Tomcat och applikationsservrar (detta är ett ämne för en separat diskussion). För att göra detta, i projektstrukturen i mappen src Låt oss skapa ett paket ru.javarush.endpoint, och i det skapar vi en HelloWebServicePublisher-klass med huvudmetoden: paket ru. javarush. slutpunkt; // klass för att köra en webbserver med webbtjänster importera javax. xml. ws. Slutpunkt; // klass av vår webbtjänst import ru. javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher ( public static void main (String... args) ( // starta webbservern på port 1986 // och till adressen som anges i det första argumentet, // starta webbtjänsten som skickas i det andra argumentet Slutpunkt. publicera( "http://localhost:1986/wss/hello", nya HelloWebServiceImpl () ); ) ) Låt oss nu köra den här klassen genom att klicka Skift+F10. Inget kommer att visas i konsolen, men servern är igång. Du kan verifiera detta genom att skriva raden http://localhost:1986/wss/hello?wsdl i din webbläsare. Sidan som öppnas bevisar å ena sidan att vi har en webbserver (http://) som körs på port 1986 på vår dator (localhost), och å andra sidan visar den en WSDL-beskrivning av vår webbtjänst. Om du stoppar applikationen blir beskrivningen otillgänglig, liksom webbtjänsten själv, så vi kommer inte att göra detta utan går vidare till att skriva klienten.

Klient

I projektmappen src Låt oss skapa ett paket ru.javarush.client , och i det klassen HelloWebServiceClient med huvudmetoden: paket ru. javarush. klient; // behövs för att få wsdl-beskrivning och genom den // nå själva webbtjänsten importera java. netto. URL; // detta undantag kommer att inträffa när du arbetar med ett URL-objekt importera java. netto. Felaktig URL-undantag; // klasser för att analysera xml med wsdl-beskrivning // och nå servicetaggen i den importera javax. xml. namnutrymme. QName; importera javax. xml. ws. Service; // gränssnitt för vår webbtjänst (vi behöver mer) import ru. javarush. ws. HelloWebService; public class HelloWebServiceClient (public static void main (String args) kastar MalformedURLException ( // skapa en länk till wsdl-beskrivning URL url = ny URL ( "http://localhost:1986/wss/hello?wsdl") ; // Vi tittar på parametrarna för nästa konstruktor i den allra första taggen i WSDL-beskrivningen - definitioner // titta på det första argumentet i targetNamespace-attributet // titta på det andra argumentet i namnattributet QName qname = new QName ("http://ws.javarush.ru/" , "HelloWebServiceImplService" ) ; // Nu kan vi nå servicetaggen i wsdl-beskrivningen, Serviceservice = Service. skapa (url, qname); // och sedan upp till porttaggen kapslad i den, så att // få en länk till ett webbtjänstobjekt på avstånd från oss HelloWebService hej = tjänst. getPort(HelloWebService.class); // Hurra! Du kan nu anropa fjärrmetoden Systemet. ut. println (hej. getHelloString ("JavaRush") ); ) ) Jag gav maximala kommentarer om koden i listan. Jag har inget att tillägga, så låt oss köra (Skift+F10). Vi bör se texten i konsolen: Hej, JavaRush! Om du inte såg det, har du förmodligen glömt att starta webbtjänsten.

Slutsats

Detta ämne gav en kort utflykt till webbtjänster. Återigen kommer jag att säga att mycket av det jag skrev är min gissning om hur det fungerar, och därför ska du inte lita för mycket på mig. Jag skulle vara tacksam om kunniga personer rättar mig, för då lär jag mig något. UPD.

Ämnets rubrik är verkligen en fråga, för... Jag vet inte själv vad det är och för första gången ska jag försöka arbeta med det inom ramen för denna artikel. Det enda jag kan garantera är att koden som presenteras nedan kommer att fungera, men mina fraser kommer bara att vara antaganden och gissningar om hur jag själv förstår allt detta. Låt oss gå...

Introduktion

Vi måste börja med varför konceptet webbtjänster skapades. När detta koncept dök upp i världen fanns det redan teknologier som gjorde det möjligt för applikationer att interagera på avstånd, där ett program kunde anropa någon metod i ett annat program, som kunde startas på en dator i en annan stad eller till och med ett land. Allt detta förkortas RPC (Remote Procedure Calling). Exempel inkluderar CORBA-teknologier och för Java - RMI (Remote Method Invoking). Och allt verkar vara bra i dem, speciellt i CORBA, för... Du kan arbeta med det i vilket programmeringsspråk som helst, men något saknades fortfarande. Jag tror att nackdelen med CORBA är att den fungerar genom några av sina egna nätverksprotokoll istället för enkla HTTP, som passar genom vilken brandvägg som helst. Tanken med webbtjänsten var att skapa en RPC som skulle infogas i HTTP-paket. Därmed började utvecklingen av standarden. Vilka är de grundläggande begreppen i denna standard:
  1. TVÅL. Innan du anropar en fjärrprocedur måste du beskriva detta samtal i en XML-fil i SOAP-format. SOAP är helt enkelt en av de många XML-uppmärkningar som används i webbtjänster. Allt vi vill skicka någonstans via HTTP konverteras först till en XML SOAP-beskrivning, stoppas sedan i ett HTTP-paket och skickas till en annan dator i nätverket via TCP/IP.
  2. WSDL. Det finns en webbtjänst, d.v.s. ett program vars metoder kan anropas på distans. Men standarden kräver att det här programmet åtföljs av en beskrivning som säger att "ja, du har rätt - det här är verkligen en webbtjänst och du kan anropa sådana och sådana metoder från den." Denna beskrivning representeras av en annan XML-fil, som har ett annat format, nämligen WSDL. De där. WSDL är bara en XML-fil som beskriver en webbtjänst och inget mer.
Varför så kortfattat frågar du? Kan du inte vara mer specifik? Det är förmodligen möjligt, men för att göra detta måste du vända dig till böcker som T. Mashnin, "Java Web Services". Där, under de första 200 sidorna, finns en detaljerad beskrivning av varje tagg i SOAP- och WSDL-standarderna. Är det värt att göra? Enligt min åsikt nej, för... allt detta skapas automatiskt i Java, och du behöver bara skriva innehållet i de metoder som är tänkta att kallas på distans. Så ett API som JAX-RPC dök upp i Java. Om någon inte vet, när de säger att Java har ett sådant och ett API, betyder det att det finns ett paket med en uppsättning klasser som kapslar in den aktuella tekniken. JAX-RPC utvecklades med tiden från version till version och blev så småningom JAX-WS. WS står uppenbarligen för WebService och du kanske tror att detta helt enkelt är ett byte av RPC som ett populärt modeord nuförtiden. Detta är inte sant, eftersom Nu har webbtjänster gått bort från den ursprungliga idén och låter dig inte bara anropa fjärrmetoder, utan också att helt enkelt skicka dokumentmeddelanden i SOAP-format. Jag vet inte varför detta behövs ännu; det är osannolikt att svaret här kommer att vara "ifall det behövs." Själv skulle jag vilja lära mig av mer erfarna kamrater. Och sist, då dök JAX-RS upp för så kallade RESTful webbtjänster, men detta är ämnet för en separat artikel. Introduktionen kan sluta här, eftersom... Därefter ska vi lära oss att arbeta med JAX-WS.

Allmän riktlinje

I webbtjänster finns det alltid en klient och en server. Servern är vår webbtjänst och kallas ibland för slutpunkten (som i slutpunkten dit SOAP-meddelanden från klienten når). Vi behöver göra följande:
  1. Beskriv gränssnittet för vår webbtjänst
  2. Implementera detta gränssnitt
  3. Starta vår webbtjänst
  4. Skriv en klient och fjärranrop önskad webbtjänstmetod
Du kan starta en webbtjänst på olika sätt: antingen beskriva en klass med huvudmetoden och starta webbtjänsten direkt som en server, eller distribuera den till en server som Tomcat eller någon annan. I det andra fallet startar vi inte själva en ny server och öppnar inte en annan port på datorn, utan säger helt enkelt till Tomcat servletcontainern att ”vi har skrivit webbtjänstklasser här, vänligen publicera dem så att alla som kontaktar dig kan använd vår användning av webbtjänsten." Oavsett sätt att lansera webbtjänsten kommer vi att ha samma klient.

Server

Låt oss lansera IDEA och skapa ett nytt projekt Skapa nytt projekt. Låt oss ange namnet Hej WebService och tryck på knappen Nästa, sedan knappen Avsluta. I mapp src låt oss skapa ett paket ru.javarush.ws. I det här paketet kommer vi att skapa HelloWebService-gränssnittet: package ru. javarush. ws; // dessa är anteckningar, dvs. ett sätt att markera våra klasser och metoder, // relaterat till webbtjänstteknik importera javax. jws. WebMethod; importera javax. jws. Webb-service; importera javax. jws. tvål. SOAPBindning; // vi säger att vårt gränssnitt kommer att fungera som en webbtjänst@Webb-service // vi säger att webbtjänsten kommer att användas för att anropa metoder@SOAPBinding (stil = SOAPBinding. Style. RPC) offentligt gränssnitt HelloWebService ( // vi säger att denna metod kan kallas på distans@WebMethod public String getHelloString(String name) ; ) I den här koden är klasserna WebService och WebMethod så kallade annoteringar och gör ingenting förutom att markera vårt gränssnitt och dess metod som en webbtjänst. Detsamma gäller för SOAPBinding-klassen. Den enda skillnaden är att SOAPBinding är en annotering med parametrar. I det här fallet används stilparametern med ett värde som indikerar att webbtjänsten inte kommer att fungera genom dokumentmeddelanden, utan som en klassisk RPC, d.v.s. att anropa en metod. Låt oss implementera vår gränssnittslogik och skapa en HelloWebServiceImpl-klass i vårt paket. Förresten, jag noterar att att avsluta en klass med Impl är en konvention i Java, enligt vilken implementeringen av gränssnitt är så betecknad (Impl - från ordet implementering, dvs implementering). Detta är inget krav och du är fri att benämna klassen vad du vill, men gott uppförande kräver det: paket ru. javarush. ws; // samma anteckning som när man beskriver gränssnittet, importera javax. jws. Webb-service; // men här används den med parametern endpointInterface, // som anger det fullständiga namnet på gränssnittsklassen för vår webbtjänst@WebService(endpointInterface= "ru.javarush.ws.HelloWebService") public class HelloWebServiceImpl implementerar HelloWebService ( @Override public String getHelloString (String name) ( // returnera bara hälsningen returnera "Hej, " + namn + "!" ; ) ) Låt oss lansera vår webbtjänst som en oberoende server, d.v.s. utan deltagande av någon Tomcat och applikationsservrar (detta är ett ämne för en separat diskussion). För att göra detta, i projektstrukturen i mappen src Låt oss skapa ett paket ru.javarush.endpoint, och i det skapar vi en HelloWebServicePublisher-klass med huvudmetoden: paket ru. javarush. slutpunkt; // klass för att köra en webbserver med webbtjänster importera javax. xml. ws. Slutpunkt; // klass av vår webbtjänst import ru. javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher ( public static void main (String... args) ( // starta webbservern på port 1986 // och till adressen som anges i det första argumentet, // starta webbtjänsten som skickas i det andra argumentet Slutpunkt. publicera( "http://localhost:1986/wss/hello", nya HelloWebServiceImpl () ); ) ) Låt oss nu köra den här klassen genom att klicka Skift+F10. Inget kommer att visas i konsolen, men servern är igång. Du kan verifiera detta genom att skriva raden http://localhost:1986/wss/hello?wsdl i din webbläsare. Sidan som öppnas bevisar å ena sidan att vi har en webbserver (http://) som körs på port 1986 på vår dator (localhost), och å andra sidan visar den en WSDL-beskrivning av vår webbtjänst. Om du stoppar applikationen blir beskrivningen otillgänglig, liksom webbtjänsten själv, så vi kommer inte att göra detta utan går vidare till att skriva klienten.

Klient

I projektmappen src Låt oss skapa ett paket ru.javarush.client , och i det klassen HelloWebServiceClient med huvudmetoden: paket ru. javarush. klient; // behövs för att få wsdl-beskrivning och genom den // nå själva webbtjänsten importera java. netto. URL; // detta undantag kommer att inträffa när du arbetar med ett URL-objekt importera java. netto. Felaktig URL-undantag; // klasser för att analysera xml med wsdl-beskrivning // och nå servicetaggen i den importera javax. xml. namnutrymme. QName; importera javax. xml. ws. Service; // gränssnitt för vår webbtjänst (vi behöver mer) import ru. javarush. ws. HelloWebService; public class HelloWebServiceClient (public static void main (String args) kastar MalformedURLException ( // skapa en länk till wsdl-beskrivning URL url = ny URL ( "http://localhost:1986/wss/hello?wsdl") ; // Vi tittar på parametrarna för nästa konstruktor i den allra första taggen i WSDL-beskrivningen - definitioner // titta på det första argumentet i targetNamespace-attributet // titta på det andra argumentet i namnattributet QName qname = new QName ("http://ws.site/", "HelloWebServiceImplService"); // Nu kan vi nå servicetaggen i wsdl-beskrivningen, Serviceservice = Service. skapa (url, qname); // och sedan upp till porttaggen kapslad i den, så att // få en länk till ett webbtjänstobjekt på avstånd från oss HelloWebService hej = tjänst. getPort(HelloWebService.class); // Hurra! Du kan nu anropa fjärrmetoden Systemet. ut. println (hej. getHelloString ("JavaRush") ); ) ) Jag gav maximala kommentarer om koden i listan. Jag har inget att tillägga, så låt oss köra (Skift+F10). Vi bör se texten i konsolen: Hej, JavaRush! Om du inte såg det, har du förmodligen glömt att starta webbtjänsten.

Slutsats

Detta ämne gav en kort utflykt till webbtjänster. Återigen kommer jag att säga att mycket av det jag skrev är min gissning om hur det fungerar, och därför ska du inte lita för mycket på mig. Jag skulle vara tacksam om kunniga personer rättar mig, för då lär jag mig något. UPD.

Idag används WEB-tjänster nästan överallt - de ger oss information om flyg- och tågflyg, växelkurser och väder. Det är inte förvånande att 1C också har förmågan att skapa sina egna WEB-tjänster, vilket gör att det kan agera både som leverantör och konsument. Denna mekanism är inbyggd i 1C:Enterprise 8.3-plattformen och utvecklare kan till och med lägga till sina egna objekt av typen WEB-tjänster till standardkonfigurationen. Deras arkitektur bygger på en uppsättning tjänster som låter dig utbyta information med annan programvara.

Skapa en 1C-webbtjänst

En av de främsta fördelarna med 1C WEB-tjänster är frånvaron av behovet av att ge direkt tillgång till informationssäkerhetsdata. En korrekt konfigurerad 1C-webbtjänst tillåter andra applikationer att använda funktioner utifrån. I sådana fall bör funktionen själv bestämma rätten att använda data enligt de angivna parametrarna enligt de regler som föreskrivs av utvecklaren.

Hur skapar man en webbtjänst i 1C?

För att en viss funktion i 1C-systemet ska bli tillgänglig för extern programvara är det nödvändigt att utföra följande algoritm för åtgärder:

  1. Gå till konfigurationen och lägg till ett WEB-tjänstobjekt i en viss gren av trädet;
  2. Beskriv alla operationer som vår funktionalitet kan utföra. Funktionsbeskrivningen utförs i modulen i det inbyggda 1C-språket;
  3. Lägg till en beskrivning av parametrarna för webbtjänstens funktioner. Observera att datatyperna beskrivs med hänsyn till de befintliga typerna av XDTO-mekanismen som introducerades i plattformsversion 8.1;
  4. Publicera den skapade WEB-tjänsten på servern. Mekanismen som är inbyggd i 1C-plattformen stöder följande standarder:
  • SSL/TLS
  • WS-I BP

Ett exempel på att skapa en enkel WEB-tjänst

För att tydligast visa hur WEB-tjänstmekanismen fungerar, låt oss skapa ett exempel - en funktionalitet som bestämmer längden på den angivna strängen. Programvaran skickar en sträng som en begäran-parameter, och funktionen som beskrivs i 1C kommer att returnera antalet tecken. När du skapar måste du komma ihåg att publicering av denna mekanism gör det möjligt för olika programvaror att komma åt den. Eftersom inte alla program kan acceptera det kyrilliska alfabetet kommer vi att namnge konfigurationsobjekt med latinska tecken.

Öppna konfiguratorn, hitta grenen "WEB services" i trädet och lägg till en ny tjänst "wa_LengthString". Du måste också lägga till en ny operation på fliken "Operations". Låt oss kalla det "CalcLengthString", ange returvärdestypen i egenskaperna - int eller heltal och skapa parametern "InputString" inuti den. Vi lämnar värdetypen som sträng.

Nu måste du registrera åtgärden för CalcLengthString-funktionen i WEB-tjänstmodulen. För att göra detta, öppna egenskaperna för den skapade funktionen och klicka på knappen i form av ett förstoringsglas till höger, bredvid inmatningsfältet "Procedurnamn". 1C kommer automatiskt att skapa en funktion i vår WEB-tjänstmodul och öppna den så att vi kan beskriva CalcLengthString-åtgärden. Låt oss dra fördel av detta och skriva funktionen för funktionen - bestämma längden på inmatningssträngen.


Detta slutför faktiskt skapandet av en enkel WEB-tjänst. Nu är det nödvändigt att "sätta" den här tjänsten i det offentliga området så att programvara från tredje part eller andra 1C-system kan använda denna funktionalitet.

För att vi ska kunna publicera den skapade webbtjänsten med dess funktionalitet behöver vi ha tillgång till sajten. Innan vi börjar publicera tjänsten måste vi kontrollera filnamnet i egenskaperna för den skapade wa_LengthString-modulen. Det ska vara tydligt, enkelt och ha tillägget "1cws".


Nu är det dags att publicera WEB-tjänsten vi skapade på servern. Denna funktion dök upp i plattformsversion 8.3 och många företag har redan insett de fulla fördelarna med denna funktion. För att börja publicera måste du öppna formuläret "Administration/Publicering på en webbserver..." i konfiguratorn.


I fönstret som öppnas måste vi konfigurera 1C Web Services och fylla i vissa fält:

  • Namn. Anger mappen på webbservern där beskrivningen av vår webbtjänst kommer att lagras. Var försiktig med case, eftersom ibland servrar skiljer mellan stora och små case-tecken;
  • Webbserver. Du måste välja en server från de som är installerade på din dator;
  • Katalog. Du måste välja sökvägen till mappen där webbserverdata för att konfigurera anslutningen lagras. Endast latinska bokstäver används;
  • Två tecken av boolesk typ. Den första kommer att vara användbar för oss om vi behöver konfigurera åtkomst till konfigurationen via en webbklient. För att publicera en 1C-tjänst måste du markera den andra rutan.

Allt som återstår är att kontrollera att den önskade WEB-tjänsten har kryssrutan markerad i den första kolumnen och klicka på "Publicera".


Eftersom den här mekanismen fortfarande är ganska ny, kan du stöta på ett fel som "Ett fel inträffade när en filoperation utfördes...". I det här fallet behöver du bara klicka på "Publicera" igen. I de flesta fall kommer detta att hjälpa och du kommer att se ett meddelande som indikerar att webbtjänsten har publicerats.

<имяСервера>.ru/<ИмяУказанногоКаталогаНаСервере>/ws/<НаименованиеФайла>.1cws?wsdl

Som svar på en sådan adressbegäran måste webbläsaren visa strukturen för XML-filen. Om du ser en tom sida, ett fel eller konstiga tecken (kodningsproblem), måste du kontrollera alla steg igen. Det är också en bra idé att se till att servern är korrekt konfigurerad och att du har tillgång till den. Efter framgångsrik publicering kommer 1C WEB-tjänsten att kunna användas av tredjepartsapplikationer.


Nyckelord: webbtjänst, webbtjänst, SOAP, WSDL, ws länk

Friskrivningsklausul och användarvillkor

Alla varumärken som av misstag nämns i denna artikel tillhör sina respektive ägare.
Den här artikeln är publicerad under en Creative Commons Attribution-Share Alike 3.0 Unported-licens. http://creativecommons.org/licenses/by-sa/3.0/

Ytterligare en ansvarsfriskrivning (efter många gånger)

1C:Enterprise 8-plattformen utvecklas ständigt. Därför kommer koden som presenteras i den här artikeln att generera ett fel i de senaste versionerna av plattformen. Detta händer särskilt på grund av det faktum att ordningen för anropsmetoder för ett webbtjänstproxyobjekt har ändrats: till exempel måste komplexa objekt explicit konverteras till ett XDTO-objekt av lämplig typ med hjälp av fabriken för motsvarande tjänst . Du kan läsa om detta på vårt forum eller i boken "1C:Enterprise Integration Technologies" http://v8.1c.ru/metod/books/book.jsp?id=288

Introduktion

När en ny version av en mjukvaruprodukt dyker upp vill du naturligtvis först och främst förstå vad som är nytt i den. I fallet med 1C:Enterprise 8.1 blev webbtjänster en sådan ny "funktion" för mig. Mycket har skrivits och sagts om webbtjänster, eftersom denna teknik har funnits ganska länge med datorstandard. Därför kommer jag inte att upprepa mig själv, jag hänvisar alla till Yandex för information. Jag kommer bara att säga att med lanseringen av den nya utgåvan av 1C:Enterprise 8.1-plattformen har 1Snikov möjlighet att skapa och använda webbtjänstteknik, så att säga, i sin ursprungliga miljö. I den här artikeln vill jag visa hur du använder externa webbtjänster i din utveckling.

För dem som är helt "utanför loopen": om webbtjänster "till hands"

OK, speciellt för dig Jag ska försöka berätta lite om vad en webbtjänst är och varför exakt Detta Det verkade för mig som en sådan "läcker" innovation av plattformen. Kanske känner du till COM-teknik eller hört något om OLE? Förr eller senare kommer varje enskild arbetare att stöta på den här tekniken (särskilt om du snabbt behöver överföra någon katalog "Anställda", och HR-avdelningen, som förutser behovet av att driva in alla 1 500 anställda igen, är redo att hänga dig på den första passande spik som följer med).
Ja, så, i hjärtat av COM-tekniken är idén om möjligheter anropa programkod (och komma åt data) för en applikation från en annan applikation. Dessutom, möjligheter gör detta inte på nivån för individuella procedurer och funktioner, utan genom att stå till förfogande föremål en annan applikation. När vi använder OLE skapar vi ett objekt i vår applikation som är " representativ"eller, om du föredrar," omslag"av något objekt i applikationen som vi vill interagera med (det så kallade "OLE-objektet" eller "COM-objektet"). Genom detta "wrapper"-objekt blir egenskaperna och metoderna för objektet för en annan applikation tillgängliga för oss , och endast de som utvecklaren Togo Appar tillät oss att använda genom att publicera dem i beskrivningen gränssnitt. (Tja, jag ville inte komma in i ogräset, men det finns inget annat sätt...)
Låt oss nu föreställa oss det exakt samma applikationen finns på en annan dator, och inte ens på det lokala nätverket (DCOM, CORBA och andra absurda förkortningar hanterar sådana fall bra), utan någonstans långt, långt borta på Internet. Det är här webbtjänster kommer in på scenen (även komplett med abstrusa akronymer: SOAP, WSDL, etc.), som låter dig utföra ett liknande "trick" i det här fallet: d.v.s. ta emot data och manipulera objekt från ett program som körs på en dator på andra sidan internet.
Under " extern"med webbtjänst menar jag en webbtjänst som tillhandahålls för vissa leverantör tjänst (dvs inte vår applikation.) Följaktligen, av "intern" - webbtjänsten som vi kommer att tillhandahålla från, eller mer exakt, baserad vår ansökan. När vi använder externa webbtjänster måste vi förstå att även om "wrapper"-objektet skapas i vår "lokala" applikation, finns "exekveringskoden" för detta objekt, kanske, på andra sidan jordklotet. Samtidigt, utbytet mellan oss Och dem utspelar sig på den nu allestädes närvarande XML, med dess välkända "pros" (mångsidighet och struktur) och "nackdelar" (bloat), och den gamla goda http används som "överföringslinje".
Ja, och glöm inte internettrafiken! Dessutom, när det gäller externa webbtjänster, kommer det mesta att vara på inkommande komponent.
Allt annat finns i Yandex. Låt oss gå vidare...

Var är benen ifrån, d.v.s. vingar växer

Efter att ha rotat igenom Yandex hittade jag en underbar webbtjänst från företaget Aeroflot, som låter dig ta emot information om ankomst och avgång av flygplan i realtid, och jag bestämde mig för att göra en slags "Airport Display" i 1C:Enterprise. Själva tjänsten finns här: http://webservices.aeroflot.ru/desc_flightinfo.asp

Han sa: "Låt oss gå!"

Till att börja med skapade jag en tom konfiguration av "1C:Enterprise 8.1" (i skrivande stund hade jag plattformsversion 8.1.5.123 till mitt förfogande). Sedan lade jag till ett nytt objekt av typen WS-link till min konfiguration. När jag blev ombedd att ange URL:en för den importerade WSDL, angav jag en länk till WSDL-filen, som finns listad på tjänstsidan: http://webservices.aeroflot.aero/flightstatus.wsdl (WSDL-filen är en beskrivning av webbtjänst. För detaljer, gå till Yandex ), och döpte stolt den skapade anläggningen till "Aeroflot". Genom att dubbelklicka på det här objektet fick jag ett träd med strukturen av en webbtjänst.

Detta träd representerar ett "porträtt" av webbtjänsten, som 1Ska ser det. Det mest intressanta är i grenen "Webtjänster": detta namn Och hamnar webbtjänster (i själva verket kan en WSDL-fil beskriva inte en, utan flera webbtjänster, då kommer varje webbtjänst att ha sin egen filial), och listas metoder webb-service. Dessa är själva "strängarna", genom att dra i dem kan du ge dig själv tillgång till den data som webbtjänsten tillhandahåller. Grenen "Datamodell" innehåller en beskrivning av de datatypsbibliotek som används av webbtjänsten.
En kort sammanfattning av hur du använder webbtjänsten finns vanligtvis på samma ställe som länken till WSDL-filen. När det gäller Aeroflot är detta sidan http://webservices.aeroflot.aero/flightstatus.asmx

"Nu start, nu landar..."

För att arbeta med webbtjänsten lade jag till "Departures Display" bearbetning i konfigurationen, och i den - en form, som jag angav som den huvudsakliga. På formuläret placerade jag urvalsfältet "Airport Selection", inmatningsfältet "Flight Date", panelen "Tableboard Panel" med två sidor "Ankomster" och "Departures", medan jag avmarkerade flaggan "Distribute across pages" i panelegenskaper och tabellfältet "Tableboard" ".
Interaktion med en webbtjänst sker enligt "request-response"-principen och ett speciellt mellanliggande objekt skapas för webbtjänsten. Därför lade jag till "ServiceAeroflot"-formulärdetaljerna av en anpassad typ.
Om du noggrant läser beskrivningen av tjänsten kan du se att webbtjänsten tillhandahåller data om ankomster och avgångar genom samtal till Ankomst- respektive Avgångsmetoderna. I det här fallet tar båda metoderna flygplatskoden och önskat datum som parametrar. Dessutom ger webbtjänsten möjlighet att få en lista över flygplatser för vilka data finns tillgänglig i systemet. Följande scenario för interaktion med en webbtjänst är ganska uppenbart:
1. Få en lista över flygplatser;
2. Välj önskad flygplats och datum;
3. Få uppgifter om ankomster eller avgångar;
Men innan du kommer åt webbtjänsten måste du initiera ett mellanliggande objekt (som WSProxy), vilket är vad jag gjorde i formuläröppningshanteraren:
ServiceAeroflot=WSLinks.Aeroflot.CreateWSProxy(" http: //www.aeroflot.ru/", "FlightStatus", "FlightStatusSoap");
Den första parametern är URI:n för webbtjänstens namnutrymme. Du kan ta reda på det genom att öppna webbtjänstens egenskaper i WS-länkträdet. De andra och tredje parametrarna överför namnet och porten för webbtjänsten.
(blanda inte ihop begreppen "namn", "port", "proxy" etc. som de tillämpas på webbtjänster med de mer välbekanta begreppen i TCP/IP-protokollet. Om det finns en överensstämmelse mellan dem är det ganska semantiskt I det allmänna fallet måste du förstå att till exempel en webbtjänstport och en TCP-port är helt olika saker).
Sålunda initierade jag Aeroflot Service-objektet av WSProxy-typen, som i huvudsak är en "wrapper" av webbtjänsten. Genom den kan jag komma åt webbtjänstmetoder som "inbyggda" metoder för plattformen.
Först och främst fick jag en lista över flygplatser och fyllde i listan över valfältet "Välj flygplats":

SelectionList=FormElements.AirportSelection.SelectionList; SelectionList.Clear(); AirportList=Aeroflot Service.AirportList().GetList("list "); TotalAirports=ListAirports.Count(); För ui=0 till TotalAirports-1 Cycle Airport=ListAirports.Get(es); SelectionList.Add(Airport.code, ""+Airport.city+" : "+Flygplats.namn); EndCycle;
Här behöver vi en liten kommentar om konstruktionen av Airport List = ServiceAeroflot.AirportList().GetList("list");
Faktum är att värdena som returneras av webbtjänstmetoder representeras i plattformen av objekt av typen XDTO Object. Eftersom ämnet XDTO-teknik ligger utanför ramen för denna artikel, kommer jag bara att säga det för transformationer detta objekt i en lista (vilket det är), kallade jag dess GetList()-metod. Resten av koden är ganska uppenbar, inklusive namnen på fälten i flygplatsstrukturen, som jag hittade på webbtjänstens beskrivningssida.
Nu kan du köra konfigurationen och se till att urvalsfältslistan är fylld med flygplatsnamn:

"Avresa, ankomstdag..."

Nu har jag nästan allt klart för att få min resultattavla att fungera. Allt som återstår är att "måla det och slänga det" :) Det är vad jag ska göra:

Procedur FillTableboard(Arrival=True) TableTableboard.Columns.Clear(); TableTableboard.Columns.Add("Flygkod", "Flygkod"); TableTableboard.Columns.Add(" Flygbolagskod", "Flygbolag"); TableTable.Columns.Add("FlightNumber", "Number"); TableTable.Columns.Add(" AirportTransit", "Flygplatstransitering"); TableTable.Columns.Add("Flygplats", "Flygplats"+?(Ankomster,"avgångar",","ankomster")); TableTable.Columns.Add(" Tidsschema", "På schema"); TableTableboard.Columns.Add(" Planerad tid", "Planerad"); TableTableboard.Columns.Add(" TimeActual", "Faktisk"); TableTable.Columns.Add("Beräknad tid", "Beräknad"); TableTable.Columns.Add("Landningstid", ?(Ankomst,"Landning","Takeoff")); TableTable. Columns. Add("Kombinerad flygning", "Kombinerad flygning"); TableTable.Columns.Add("Status", "Status"); Om inte ankomst då TableTable.Columns.Add("Registrering", "Registrering"); TableTable .Kolumner .Add("Landing", "Landing"); EndIf; Formelement. Resultattavlatabell. Skapa kolumner(); Formelement. Resultattavlatabell. Kolumner. Flygkod. Synlighet = Falskt; Om inte ankomst så Formelement. Resultattavla Tabell. Kolumner. Beräknad tid. Visibilitet = Falskt; EndIf; If Arrival Then Data=Aeroflot Service.Arrival(Airport Selection, Flight Date).Hämta List("lista "); Annars Data=Aeroflot Service.Departure(Flygplatsval, Flight Date). Datum). Get List("list "); EndIf; Total Records=Data.Number( ); För ii=0 för TotalRecords-1 Cycle Record=DATA.Get(s); NewRow=TableTable.Add(); NewRow. AirlineCode=Record.company; NewLine.FlightNumber = Entry.flight_no; NewLine.AirportTransit = Entry.airport_inter; NewLine.Airport = Entry.airport; NewLine.TimeSchedule=Record.sched; NewLine.TimePlanned=Record.plan; NewLine.TimeActual=Record.fact; NewLine.TimeCalculated=Record.calc; NewLine.LandingTime=Rekord.real; NewLine.UnionFlight=Record.union_flight_no; NewRow.Status=Rekord.status; Om inte ankomst då NewLine.Registration=Record.is_check; NewLine.Landing = Entry.is_board; endIf; EndCycle; Slut på procedur

För att kontrollera hur det hela fungerar lade jag till en "Uppdatera" -knapp med en motsvarande bild till formulärets kommandopanel, och i dess hanterare skrev jag följande:

Procedur CommandPanel1 Update(Button) FillTableboard(FormElements.TableboardPanel.CurrentPage=FormElements.TableboardPanel.Pages.Arrivals); Slut på procedur
Jag sparar, kör, väljer, klickar, hämtar:

Efterord

Överraskande nog, efter att artikeln skrevs och publicerades, visade det sig att den respekterade ZAV redan hade publicerat ett liknande exempel på IT-Land: http://itland.ru/biblio/detail.php?ID=1060
För att undvika eventuella anklagelser om plagiat rekommenderar jag starkt att du också läser den här artikeln och jämför författarnas tillvägagångssätt.