Scheme of operation of the 1C web service. Web services. Providing functionality through Web services


Purpose of this article– help to understand “how” WEB services are structured in 1C, understand “how the mechanisms work” and “for what tasks” it is rational to use these mechanisms.

Feature of the article is that:

  • Various methods and techniques that can be used when integrating 1C, WEB (php) and mobile (Ios, Android) applications are considered (and compared with each other);
U different ways have their pros/cons, and it is rational to choose the simplest, compact one for a specific task.
  • At the same time, examples of solutions are given both on the 1C side and on the WEB server (PHP) side;
Examples of solutions can be useful for both 1C programmers and WEB specialists, those who work at the intersection of areas.
  • All the necessary information has been collected together ( step by step instructions) to make a “quick start” and begin development. That is, so as not to waste a lot of time studying and configuring WEB servers, windows, “fighting” system errors etc.
The article is addressed to:
  • 1C: Programmers and WEB specialists studying integration using web services technology;
  • Designers and IT analysts need to understand the “essence” and make a rational choice of technologies when creating projects.
In conclusion of the introductory part, it is worth saying that if you have already had experience working with COM/Ole technologies, then this will help you well in understanding the technology of WEB services.

1.1 Technology capabilities, support by the 1C platform

1.2 Applicability of technologies for client-server interaction tasks.


2. Fast start. Where to begin?


Point No. 0.
First of all, you need to choose (decide) on the integration technology and understand the “essence” - that is, how it will work.
In other words, you need to answer two questions:

  • Which 1C database (or other program) will act as a client, and which as a server;
When determining what will be the client and what will be the server, you can use simple rule: The client can "call" (control) the server, but callback is not possible.
  • Which client-server interaction technology is most suitable for you and will be used.
I outlined my recommendations for choosing technology above.

Point No. 1.
So, the “essence” of client-server interaction is understood. Interaction technology has been determined. Now you need to create a “testing ground” where development will take place.

In this article, two technologies will be discussed using examples:

Working with the WEB services mechanism.

Examples of work from 1C 8 and PHP will be considered;

Working with the http request mechanism (REST Web services).

Examples of work from 1C 8 and PHP will also be considered;
In tasks related to WEB development, it is traditionally accepted:

  • Create a “testing ground” for development and debugging on the programmer’s local WEB server (localhost);
  • After development is completed, the results must be transferred to the “combat” WEB server.

In practice (especially when you begin to “get acquainted” with the technology of WEB services), when creating a “testing ground”, as well as when transferring a project to a “combat” server, a lot of “rake” arises.

So, so as not to “waste” a lot of time “fighting” with the settings IIS(Internet Information Server) / mastering the server apache, and setting up rights Windows access, I recommend the following:

  • (1) Create the "Polygon" on your local working machine. Operating system - Windows 7 (professional or maximum). All work must be done under account administrator.
  • (2) Deploy the 1C 8 database in client-server mode (MS SQL server, I recommend 2008 R2). Using 1C 8 in client-server mode will eliminate the need to perform additional work. settings for access rights to the 1C database from the WEB server.
  • (3) Install IIS, if it is missing. In Windows you can “re-install” it regularly

The checkboxes for the installation options for IIS components can be set by default.
The important things you need to pay attention to are the following options (ISAPI extensions - this is needed for soap connections to work in WEB services, and CGI - this is required for PHP to work)

After installation is complete IIS Let's make sure it works. For this, in address bar WEB browser enter:

(4) Publishing (connecting) a 1C database on a WEB server.

And so, WEB server IIS installed and working. Let's publish our 1C database and check that access to it is now possible through the WEB client too.

It is advisable to publish on a WEB server the 1C database that provides for operation in managed application (thin client) mode.

Publishing a 1C database is done like this:
In the configurator mode, you need to call the item "Publish on a web server"

b) Specify publication parameters:

That is, in a directory (folder) wwwroot your his IIS you need to create a separate folder (directory) for publishing your 1C database.

the wwwroot directory will be created automatically when IIS is installed
Let's create and select such a folder (wsBase10), specify the name for publication (we'll also call it wsBase10).

If, suddenly, you receive a message in response,

then don't be scared.

The 1C publishing mechanism is very capricious. Try clicking "Publish" again.

And if as a result you receive a message,

that means everything worked.

It is very important to understand that when publishing a 1C database and its WEB services on a “combat” server (for example, Windows 2008 R2), errors often occur if you decide to use a web server IIS.

Advice: do not install on a "combat" server IIS! Install apache.

This will protect you from many system errors. And publication (republishing - with changes in the configuration) will take place for apache smoothly, without the need to tinker with vrd files and settings IIS.

In this article I will not consider the installation process and apache settings. There are other sources on this topic.

However, for collaboration apache with the 1C database (and web services) there are several very important requirements that you need to know (bring this to your system administrator).

1. When installing apache Be sure to enable support for ISAPI extensions.

2. Enable cgi-bin support if you will be working with PHP;

3. You will need to enter a special “user” into the 1C database...

This user must have authentication operating system. And you need to specify the user under whose name it is launched apache.

... We're done with apache and let's return to our "Polygon" again.

Here we see - 1C is starting. The WEB server together with 1C is working.
4. Install PHP service for WINDOWS.

You will need it if, as part of your task, you need to develop client (web pages for accessing 1C) or server (scenarios for processing http requests from 1C) in PHP.

5 Let's add the wsClient10 directory to IIS, in which our PHP scripts will run.

PHP scripts we will use:

  • To create the client part when developing 1C WEB services;
  • For the development of the server part, when developing REST web services (http requests).

6. Let's install the Notepap++ program. This compact and convenient program I recommend using it to edit PHP scripts.

After installing Notepad++, we’ll immediately check that PHP is working for us. Let's create a simple hello.php script for this. Let's place it in the wsClient directory and run the script from the browser:

All OK. PHP is working. The test site is completely ready.

3. Creation of a WEB service, soap requests, XDTO and JSON. Examples 1C and PHP. At this stage, you should have “Polygon” ready and you can start developing WEB services.

- Where to start studying this technology? Of course, with a classic problem like “Hello word”!

1. The task of creating the simplest WEB service. Let's look at examples in 1C and PHP.

1.1. Let's add to the database (wsBase10) the web service "_Calculations by Tariffs"

Let's set the publication file name to "calcOrder10.1cws". The URI namespace must also be specified. In principle, you can specify any name.

1.2. Let's add the "getHello" operation within the web service "_Calculations by Tariffs".

The essence of the operation will be the simplest - take three parameters (strings, numbers) as input (from the client) and return a unifying string back to him (as a result). The return value type will be primitive - string.

We will not check the “In transaction” checkbox, since the operation will not change the data in the 1C database itself.

If our operation changed data in the 1C database, then checking this box would make sense.
The name of the method (function) that will process incoming data (and return the result) will be “getHello”.

1.3. Let's add incoming parameters for the "getHello" operation.

The direction of transmission is "input". That is, they are transferred from the client to the server.

1.4. Let's write a handler for the "getHello" operation in the web service module
///////////////////

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

////////

1.5. At this point, the work on creating a simple WEB service is completed. And now, you need to publish the WEB service "_Calculations by Tariffs".

Before publishing a web service on the test site, we will remove all users from the list of users of our information base. That is, we will make the list of users “empty”.

- Why do this?

At the test site, only the developer will be able to connect to WEB services, and therefore there is no point in providing user authentication when connecting to the WEB service.

That is, we will deliberately simplify our work with WEB services on the test site.

We will not need to specify a login and password when establishing a connection.
But on a “combat” server, of course, you will have to provide authentication.
To do this (as was said earlier), you will need to separately create a user in the “combat” database, on whose behalf the WEB server itself will be launched. And then, when establishing a connection with the WEB service (soap connection), you will also need to specify the login and password of this user.

1.6. And so, let’s publish the WEB service:

Note that we don’t have to check the “Use operating system authentication on the web server” checkbox. It's because this mode provided only for WEB server IIS, and on the “combat” server it will work Apache.

1.7. Let's create a client part and test the operation of the WEB server.

A) First, let's make a client call from 1C.

Let's do it simply. In any other 1C database that you have, we will create external processing. In this processing, we will connect to the WEB service, use the “getHello” operation, pass the parameters there and receive a response from the server.
The code for "1C" will be something like this:

/////

&OnClient
Procedure Execute Query10 (Command)
// Insert the contents of the handler.
LineResult = SERVER_ExecuteWSQuery10();
Warning(StringResult);
End of Procedure
&OnServerWithout Context
Function SERVER_RunWSRequest10()
// We will not perform authentication at the test site!
UserName = undefined;
Password = undefined;
http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ",UserName,Password);
Proxy.User = UserName;
Proxy.Password = Undefined;
strResult = Proxy.getHello("Ivanov",100.35,20);
return strResult;
EndFunction ///////////////////////////////////////////////////////////////////////////////////////

Let's test the operation of the SERVER_ExecuteWSRequest10() function.

OK. Works!
b) Now let's make a client call to the web service from PHP.
The PHP script code will be something like this:

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

error_reporting(E_ERROR); // 1. Disable unnecessary messages
// 2. Disable caching for SOAP. If this is not done,


// 3. Establish a soap connection
$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ",
array(
"login" => null, //login, we will not perform authentication
"password" => null, //password
"trace" => true,
"features" => SOAP_USE_XSI_ARRAY_TYPE,
//"compression" =>
);
// 4. Filling the array of passed parameters
$params["strParametr"] = "test_Soap10:";
$params["floatParametr"] = 10.34;
$params["integerParametr"] = 12;
// 5. Perform the getHello operation
$result = $client->getHello($params);
// 6. Display the result on the screen
var_dump($result);
?>

////
///

Let's call the script from the browser and check its operation:

Everything is fine, calling 1C from a WEB page works!

Let's summarize some results:
The problem of a simple WEB service has been solved. And now, you can start creating more complex WEB services.

And the complication will be that (so far) we have only operated with primitive data types. Of course, we will need to transmit/receive object (aggregate) data types as well.

2. The task of creating a WEB service using XDTO packages.

As before, let's look at examples in 1C and PHP.

Let's set ourselves the following task: The WEB service should return us not a string, but object data - a “table of values” (more precisely, it will be an array of objects!).

In order to describe various data structures (which will be required when receiving/transmitting to the WEB server), the 1C:8 platform provides a mechanism for XDTO packages.

Those. First we describe all the data types we need, and then we indicate:

  • What XDTO packages can our WEB service work with (you can specify either one or a list of packages);
  • For each parameter of the operation and the result it returns, you can specify what type of data (from the XDTO package) it will be.
Next, we’ll look at working with XDTO using the example of receiving a certain “tariff table” from the server:

Let's create the GetTzTariffs_0 operation, which will return data of the tzTariffs type.

The figure shows that tzTariffs includes an unlimited number of el objects. In fact, tzTariffs is a table of objects of type el.

- How to see it?

  • If the "maximum" parameter is specified as "-1", then the number of these objects is not limited (a table with an unlimited number of rows);
  • If we don’t need a table, but just need a structure (one row), then the maximum and minimum values ​​should be specified equal to “1”.
  • In turn, the el object is a structure that contains an object type attribute (eTariff) and a primitive type attribute (cPrice, comment).

Moving down the hierarchy, you can see that the tariff type is a structure (maximum and minimum quantity = 1), one of the details of which includes the kindOfTariff type.

Total: The XDTO package allows you to clearly describe the hierarchy of data types that will be used further when interacting with a WEB service.

Tip: It is better to use one XDTO package for a web service to avoid complexity and avoid design errors.
Let's move on... After:

  • The XTDO package has been created;
  • All data types are described;
  • For the WEB service, the use of this package is indicated;
  • For parameters and results of operations, the appropriate types are selected (from the XDTO package)
then you can move on to “filling” objects (structures, arrays of structures) with data.

In our example, the GetTzTariffs_0 operation should return an array of strings containing Tariffs objects.

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

Function GetTzTariffs_0()
// Insert the contents of the handler.
Return GetTZTariffs_0();
EndFunction

Function GetTZTariffs_0()


// Filling out the technical specifications
// 1st line

kindOfTariff.active = false;


tariff.kind = kindOfTariff;

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

//
// 2nd line
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);

tariff = FactoryXDTO.Create(tariffType);
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
// Add the 2nd row to the table
tzTariffs.el.Add(elementTZ);
Return tzTariffs;
EndFunction

//////////
Next, we give an example of calling the operation "GetTzTariffs_0" from the client side, from 1C.

&OnClient
Procedure Execute Query20 (Command)
// Insert the contents of the handler.
Warning(SERVER_ExecuteWSQuery20());
End of Procedure
&OnServerWithout Context
Function SERVER_ExecuteWSRequest20()
Definitions = 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();
// Let's access the line at index zero, then to the eTariff attribute, then to the nested attribute kind, then to the nested attribute name.
EndFunction

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
A similar call from PHP and processing the XDTO results would be like this:
////////////////////////////////////////////////////////////////////////////////////



// web service functions will not work correctly.
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 - an array of objects. Let's go through the elements of the array and display the results on the screen
for ($i=0; $i {
echo "
";
$eTariff = iconv("utf-8","cp1251",$mResult[$i]->eTariff->fullName);
var_dump($eTariff);
$cPrice = $mResult[$i]->cPrice;
var_dump($cPrice);
$cComment = $mResult[$i]->cComment;
var_dump($cComment);
echo "
";
}
?>

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

Now Let's complicate the task even more. Let's transfer the same object data type from the client to the WEB service (as a parameter). Let it be tzKind.
To do this, we first describe this type in the dataTariffs package, and then add the GetTzTariffs_1 operation.

Let's indicate the type of the tzKind parameter.

An example of how a WEB service works with an incoming XDTO parameter:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Function GetTZTariffs_1(tzKind)
tzTariffsType = FactoryXDTO.Type(" ", "tzTariffs");
tzTariffs = FactoryXDTO.Create(tzTariffsType);
elementTZType = FactoryXDTO.Type(" ", "elementTZ");
tariffType = FactoryXDTO.Type(" ", "tariff");
kindOfTariffType = FactoryXDTO.Type(" ", "kindOfTariff");
// Filling out the technical specifications
// 1st line
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);
kindOfTariff.name = "Transportation";
kindOfTariff.active = false;
tariff = FactoryXDTO.Create(tariffType);
tariff.fullName = "Tariff 1";
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 100;
elementTZ.comment = "Description of tariff 1";
// Add the 1st row to the table
tzTariffs.el.Add(elementTZ);
// 2nd line
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);
kindOfTariff.name = "Delivery";
kindOfTariff.active = true;
tariff = FactoryXDTO.Create(tariffType);
tariff.fullName = "Tariff 2";
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
elementTZ.comment = "Description of tariff 2";
// Add a 3rd row to the table (fill it with the incoming data)
tzTariffs.el.Add(elementTZ);
// 3rd line
kindOfTariff = FactoryXDTO.Create(kindOfTariffType);
kindOfTariff.name = tzKind.el.eKind.name;
kindOfTariff.active = tzKind.el.eKind.active;
tariff = FactoryXDTO.Create(tariffType);
tariff.fullName = "Tariff 3";
tariff.begdate = CurrentDate();
tariff.kind = kindOfTariff;
elementTZ = FactoryXDTO.Create(elementTZType);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 300;
elementTZ.comment = "Description of tariff 3";
// Add a 3rd row to the table
tzTariffs.el.Add(elementTZ);
Return tzTariffs;
EndFunction

//////////////////////////////////////////////////////////////////////////////////
From the 1C client side, we will need to prepare data of the tzKind type and transfer it to the WEB service.

Here's an example of such a call:
/////////////////////////////////////////////////////////////////////////////////

&OnClient
Procedure Execute Query30 (Command)
// Insert the contents of the handler.
Warning(SERVER_ExecuteWSQuery30());
End of Procedure
&OnServerWithout Context
Function SERVER_ExecuteWSRequest30()
Definitions = new WSDefinitions("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ");
Proxy = new WSProxy(Definitions,"www.URI.com","_Calculations By Tariffs","_Calculations By TariffsSoap");
// Create a table of parameters passed to WS
tzKindType = Proxy.FactoryXDTO.Type(" ", "tzKind");
tzKind = Proxy.FactoryXDTO.Create(tzKindType);
kindOfTariffType = Proxy.FactoryXDTO.Type(" ", "kindOfTariff");
kindOfTariff = Proxy.XDTO Factory.Create(kindOfTariffType);
kindOfTariff.name = "Test tariff type";
kindOfTariff.active = false;
elementKindType = Proxy.FactoryXDTO.Type(" ", "elementKind");
elementKind = Proxy.XDTO Factory.Create(elementKindType);
elementKind.eKind = kindOfTariff;
elementKind.qty = 10;
// Add a row to the table
tzKind.el.Add(elementKind);
XDTOResult = Proxy.GetTzTzriffs_1(tzKind);
ExampleResult_Name of Tariff Type = XDTOResult.el.eTariff.kind.name;
Return ExampleResult_Name of Tariff Type;
EndFunction

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I would like to draw your attention to the design: Proxy.FactoryXDTO.Type("...

That is, when creating an XDTO package object on the client, we must access not our own XDTO! factory, but through a Proxy. That is, to the XDTO server factory.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Now it's time to ask the question:is there any alternative to XDTO objects ?

Is it possible to “not communicate” with the XDTO factory at all, transmit/receive from a WEB service in some other way.. (especially if the client is not 1C, but for example a WEB page, an application on Android, iOS, etc.).

The answer is- yes, you can!
For example, you can use string as parameter types. And “pack” (serialize) data structures into it.

This technology in WEB programming has long been developed and is called JSON.
It’s also a big help that in PHP, packing/extracting any structure/array string is done in one step!
An example in PHP of packaging objects in JSON/extracting, transmitting/receiving to a WEB service:

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

// serialize the mDelivery array into a string and place it in the delivery parameter
// * First, let's describe the delivery structure
class delivery(
var $id;
var $checked;
var $value;
}
// Fill the structure with some data
$sDelivery = new delivery;
$sDelivery->id = "000000005";
$sDelivery->checked = TRUE;
$sDelivery->value = 0;
// Add it to the array of mDelivery objects
$mDelivery = $sDelivery;
// Convert the mDelivery array into a JSON string and place the result in the delivery parameter
$params["delivery"] = json_encode($mDelivery);
// Call the ExitCalcOrder operation on the WEB service and pass a parameter to it (string - delivery);
$result = $client->ExitCalcOrder($params);
// Get the result of the ExitCalcOrder operation into the jsCalcResult variable (string)
$jsCalcResult = $result->return;
// Perform the reverse transformation: from the jsCalcResult string to an object (an array of objects, type match) arrCalcResult
$arrCalcResult = json_decode($jsCalcResult);
// Display information on the screen about the arrCalcResult object
var_dump($arrCalcResult);

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

But how to perform JSON conversions in 1C?
The 1C 8 platform does not support the JSON standard, but this is not a problem.
JSON conversion/extraction processing exists, is available, and works great from
// Copyright © 2010-2012 Alexander Pereverzev
// 1C:JSON . JavaScript Object Notation parser and serializer.

Thus, just put this processing in your configuration and you can easily perform forward and reverse JSON conversions:
Serialization example 1C object to JSON string:

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

CargoData = new Structure;
CargoData.Insert("code",CargoCode);
CargoData.Insert("number",CargoNumber);
CargoData.Insert("plan", QuantityPlan);
CargoData.Insert("character",CargoCharacter);
CargoData.Insert("packing", Packaging);
CargoData.Insert("damage",Damage to Packaging);
CargoData.Insert("volume",Volume);
CargoData.Insert("weight",Weight);
CargoData.Insert("status",Status);
jsResult = JSON.WriteJSON(LoadData); //Convert the result to JSON
return jsResult;

Extract example object in 1C from JSON string:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1. Restore objects from JSON
JSON = Process.JSON.Create();
mdelivery = JSON.ReadJSON(delivery);
// as a result, mdelivery is an array. Array element - match.
// That is, for example, mdelivery.["id"] will contain "000000005"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
In conclusion, I will give an example of calling the 1C web service from PHP, receiving the returned JSON structure of its reverse transformation into PHP objects.

Let's pay attention to the transformations iconv("cp1251","utf-8","
and iconv("utf-8","cp1251", which will be required (when interacting with PHP - 1 C) to convert Cyrillic strings from cp 1251 encoding to utf -8 and back.

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

error_reporting(E_ERROR); // Disable messages
// Disable caching for SOAP. If this is not done,
// web service functions will not work correctly.
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["code"]);
$params["param2"] = iconv("cp1251","utf-8",$_GET["number"]);
$result = $client->executeQuery($params);
$jsResult = $result->return;
$dataFreight = json_decode($jsResult);
$statusFreight = $dataFreight->codeNm;
$numberFreight = iconv("utf-8","cp1251",$dataFreight->nameRus);
?>

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

The likely scenario is: a remote user from some of his programs (for example, from a WEB site, mobile application, etc.) calls your WEB service and... does not receive results.. Or he receives it, but something is wrong.

Question: - How to find out about such errors and debug the WEB service?
I recommend that you use a log to monitor errors (and collect incoming parameters “what led the web service to an error”).

Those. in the place where logical errors may occur, programmatically save information about incoming parameters in the registration log (LogRecord)

If you are “struggling” with “runtime errors”, then you can intercept them (an attempt is an exception) and “point-by-point” log the entire situation.

As a result, using the log, you will be able to see information about errors, reproduce the parameters of the occurrence, and “defeat” it in interactive mode, in the debugger.

Let's summarize: Examples of working with WEB services from 1C and PHP are considered. To transfer object data structures between the client and server, we used two technologies:

  • (1) XDTO packages
  • (2) JSON objects.

4. Alternative - REST Web services (http requests). Examples of implementation in 1C and PHP.
In the previous section, we examined in detail the technology of WEB services. In this section we will consider an alternative technology, the so-called. REST Web services.

A fair question arises: - Why?

WEB services are fully functional and allow you to solve problems of any complexity.

To understand “why”, let’s formulate the basic differences between these technologies.

The technology of WEB services is based on 2 points:

  • (1) SOAP connection is used. In other words, a SOAP request is made.
In "1C" soap the connection is formed as follows:
/////////////////////////////////////////////////////////////////////////////////////////

Definitions = new WSDefinitions("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",UserName,Password);
Proxy = new WSProxy(Definitions,"www.URI.com","_Calculations By Tariffs","_Calculations By TariffsSoap");

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

In PHP it's like this:

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

$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl ",
array(
"login" => login, //login,
"password" => pass, //password
"trace" => true,
"features" => SOAP_USE_XSI_ARRAY_TYPE,
//"compression" => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5
);

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

  • (2) To process a soap connection in server mode, the 1C 8 platform provides a special metadata object WEB services.

Moreover, if in your task “1C” must act as a server, then there is no alternative to 1C WEB service technology.

- When is an alternative possible?

  • Firstly, when 1C acts only as a client;
  • Secondly, when the server you need to work with (for example, a website or some kind of WEB application), it is not planned to support a SOAP connection.
- What alternative to a SOAP connection is possible?

A very popular option - http connection.

In web-based systems (PHP, Android, iOS) it is easier to work with http requests than with SOAP requests. And for not very complex projects, the http request technology is quite suitable.

The classic solution (using the http request method) is the task of integrating the 1C database and WEB site. For example, information on product range and prices is transmitted to the site, and information about accepted orders is transmitted back from the site.

It is typical that in typical 1C configurations, integration with sites is implemented using http requests.
So, let's look at the technology http requests For example interaction between 1C (client, 1C 8) and WEB site (PHP, server).

1. Establishing a connection and methods for passing parameters in an http request

An example of establishing a connection to the server from the 1C side:
/////////////////////////////////////////////////////////////////////////////

protected = false;
HTTPConnect = new HTTPConnect("localhost/wsClient10/json/testHTTPQuery11.php", Protected);

////////////////////////////////////////////////////////////////////////////
As you know, there are two methods for transferring parameters from the client to the server via the http protocol:

(1) Method "get";

Parameters (such as name and password) are specified directly in the server call URL.

That is, an interactive call to the script (directly from a WEB browser) would look like this:

In 1C:8, for programmatically calling the server (and passing parameters of Get methods to it), the “Get” method is provided.

Example:
protected = false;
HTTPConnect = new HTTPConnect("localhost", Secure);
HTTPConnect.Get("wsClient10/json/testHTTPQuery11.php?nameVasya&password=123",OutputFileName);

where OutputFileName: The name of the file into which the data returned from the server is placed.
That is, as a result of processing the request, the server returns the result to 1C and then (automatically) a file is generated that contains the result.

Accordingly, after this, in “1C” it ​​is necessary (programmatically) to read this file and extract the result obtained from it. That's all.

(2) "post" method;

In this option, the parameters are not placed in the URL, but are transmitted separately, in the body of the http connection.

It is clear that the key limitation of the method get is the volume and content of the transmitted data. That is, with the help get Only characters can be passed, and the length of the URL string is limited.

Method post You can transmit data of various contents, incl. and arbitrary files.
Thus, post for integration tasks it is more functional and we will continue to work with it.

To receive/transmit data between 1C and WEB site, we will use text files.
And we will “pack/extract” data from files using the JSON technology that is already familiar to us! This will practically save us from the need to “parse” the file on the 1C side and on the PHP side.

To call the server and transfer parameters to it using the "post" method, 1C:8 provides the method: SendForProcessing

And so, let's give an example in which on the side 1C all processing steps are carried out http request:

First, let’s write down the action plan (enlarged):

And now, its software implementation in 1C:8

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

// 1. Fill in the structure of the transmitted data
postDataToPHP = new Structure;
postDataToPHP.Insert("param1","ivanon");
postDataToPHP.Insert("param2","ivan");
postDataToPHP.Insert("param3","ivanovich");

// 2. Convert the data to a JSON string
JSON = Process.JSON.Create();
jsPostDataToPHP = JSON.WriteJSON(postDataToPHP);


// 3. Create a temporary outgoing message (transmitted to the server using the POST method)
// file, put a JSON string in it.
tFile = new TextDocument;
stringData = jsPostDataToPHP;
tFile.AddLine(stringData);


// 4. Get the name for the temporary outgoing file. It will contain the outgoing data in the form of a JSON string
OutgoingFileName = GetTemporaryFileName(".txt");

tFile.Write(OutgoingFileName,TextEncoding.UTF);

// 5. Get the name for the temporary input file. It will receive a JSON string: PHP server response
InputFileName = GetTemporaryFileName(".txt");


// 6. Establish an HTTP connection with the server
protected = false;
HTTPConnect = new HTTPConnect("localhost/wsClient10/json/testHTTPQuery10.php", Protected);


// 7. Let's execute an HTTP request. Let's transfer the outgoing file to the server (the file contains a JSON object, i.e. outgoing parameters)


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


// And we will receive a response from the server (incoming file). The file contains a //JSON object (i.e. data returned from the server)

// 8. Extract the data received from the server from the incoming file
ResponseFile = new TextDocument;
ResponseFile.Read(InputFileName,TextEncoding.UTF);
json_Data = ResponseFile.GetString(1);
mData = JSON.ReadJSON(json_Data);


// 9. Display the received data for the user
Report(mData["v1"]);
Report(mData["v2"]);


// 10. Delete used (no longer needed) temporary files.
DeleteFiles(OutgoingFileName);
DeleteFiles(InputFileName);

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

And finally, example in PHP for processing a request on the server side:

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

// 1. Get string data from the incoming file
$json_filedata = file_get_contents("php://input");
// 2. Cut off all unnecessary (2 service characters are added), which // interferes with the conversion from JSON
$jsData = trim(ltrim($json_filedata));
$dlinaStr = strlen($jsData);
$_jsData = "";
$i=1;
while ($i<$dlinaStr) {
if ($i>2) (
$_jsData = $_jsData.substr($jsData, $i, 1);
}
$i++;
}
// 3. Convert data from JSON into an object (structure)
$mData = json_decode($_jsData);
// 4. Let's create another structure, which we will fill with data and // return to 1C
class returnData(
var $v1;
var $v2;
}
$sReturnData = new returnData;
$sReturnData->v1 = $mData->param1;
$sReturnData->v2 = $mData->param2;
// 5. Convert the structure data into a JSON string
$json_returnData = json_encode($sReturnData);
// 6. Return the data to 1C (the output data will be redirected to a file, which will be returned to 1C)
echo $json_returnData;
?>

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

That's all. Compact and functional!

5. In-demand tasks (project cases)

In conclusion, I will cite those that are de facto now most in demand by customers, and which are solved using WEB services and http requests.

The topic title is really a question, because... I myself don’t know what it is and for the first time I will try to work with it within the framework of this article. The only thing I can guarantee is that the code presented below will work, but my phrases will only be assumptions and guesses about how I myself understand all this. So, let's go...

Introduction

We need to start with why the concept of web services was created. By the time this concept appeared in the world, technologies already existed that allowed applications to interact at a distance, where one program could call some method in another program, which could be launched on a computer located in another city or even country. All this is abbreviated as RPC (Remote Procedure Calling). Examples include CORBA technologies, and for Java - RMI (Remote Method Invoking). And everything seems to be good in them, especially in CORBA, because... You can work with it in any programming language, but something was still missing. I believe that the disadvantage of CORBA is that it works through some of its own network protocols instead of simple HTTP, which will fit through any firewall. The idea of ​​the web service was to create an RPC that would be inserted into HTTP packets. Thus began the development of the standard. What are the basic concepts of this standard:
  1. SOAP. Before calling a remote procedure, you need to describe this call in an XML file in SOAP format. SOAP is simply one of the many XML markups that are used in web services. Everything we want to send somewhere via HTTP is first converted into an XML SOAP description, then stuffed into an HTTP packet and sent to another computer on the network via TCP/IP.
  2. WSDL. There is a web service, i.e. a program whose methods can be called remotely. But the standard requires that this program be accompanied by a description that says that “yes, you’re right - this is really a web service and you can call such and such methods from it.” This description is represented by another XML file, which has a different format, namely WSDL. Those. WSDL is just an XML file describing a web service and nothing more.
Why so briefly you ask? Can't you be more specific? It’s probably possible, but to do this you’ll have to turn to books such as T. Mashnin, “Java Web Services.” There, over the first 200 pages, there is a detailed description of each tag of the SOAP and WSDL standards. Is it worth doing? In my opinion, no, because... all this is created automatically in Java, and you only need to write the contents of the methods that are supposed to be called remotely. So, an API such as JAX-RPC appeared in Java. If anyone doesn't know, when they say that Java has such and such an API, it means that there is a package with a set of classes that encapsulate the technology in question. JAX-RPC evolved over time from version to version and eventually became JAX-WS. WS obviously stands for WebService and you might think that this is simply a renaming of RPC as a popular buzzword these days. This is not true, because Now web services have moved away from the original idea and allow you not only to call remote methods, but also to simply send document messages in SOAP format. I don’t know why this is needed yet; it’s unlikely that the answer here will be “just in case it’s needed.” I myself would like to learn from more experienced comrades. And lastly, then JAX-RS appeared for so-called RESTful web services, but this is the topic of a separate article. The introduction can end here, because... Next we will learn to work with JAX-WS.

General approach

In web services there is always a client and a server. The server is our web service and is sometimes called the endpoint (as in, the end point where SOAP messages from the client reach). We need to do the following:
  1. Describe the interface of our web service
  2. Implement this interface
  3. Launch our web service
  4. Write a client and remotely call the desired web service method
You can launch a web service in different ways: either describe a class with the main method and launch the web service directly as a server, or deploy it to a server like Tomcat or any other. In the second case, we ourselves do not launch a new server and do not open another port on the computer, but simply tell the Tomcat servlet container that “we have written web service classes here, please publish them so that everyone who contacts you can use our use the web service." Regardless of the method of launching the web service, we will have the same client.

Server

Let's launch IDEA and create a new project Create New Project. Let's indicate the name HelloWebService and press the button Next, then button Finish. In folder src let's create a package ru.javarush.ws. In this package we will create the HelloWebService interface: package ru. javarush. ws; // these are annotations, i.e. a way to mark our classes and methods, // as related to web service technology import javax. jws. WebMethod; import javax. jws. WebService; import javax. jws. soap. SOAPBinding; // we say that our interface will work as a web service@WebService // we say that the web service will be used to call methods@SOAPBinding (style = SOAPBinding. Style. RPC) public interface HelloWebService ( // we say that this method can be called remotely@WebMethod public String getHelloString(String name) ; ) In this code, the WebService and WebMethod classes are so-called annotations and do nothing except mark our interface and its method as a web service. The same applies to the SOAPBinding class. The only difference is that SOAPBinding is an annotation with parameters. In this case, the style parameter is used with a value indicating that the web service will work not through document messages, but as a classic RPC, i.e. to call a method. Let's implement our interface logic and create a HelloWebServiceImpl class in our package. By the way, I note that ending a class with Impl is a convention in Java, according to which the implementation of interfaces is so designated (Impl - from the word implementation, i.e. implementation). This is not a requirement and you are free to name the class whatever you want, but good manners require it: package ru. javarush. ws; // the same annotation as when describing the interface, import javax. jws. WebService; // but here it is used with the endpointInterface parameter, // indicating the full name of the interface class of our web service@WebService(endpointInterface= "ru.javarush.ws.HelloWebService") public class HelloWebServiceImpl implements HelloWebService ( @Override public String getHelloString (String name) ( // just return the greeting return "Hello, " + name + "!" ; ) ) Let's launch our web service as an independent server, i.e. without the participation of any Tomcat and application servers (this is a topic for a separate discussion). To do this, in the project structure in the folder src Let's create a package ru.javarush.endpoint, and in it we will create a HelloWebServicePublisher class with the main method: package ru. javarush. endpoint; // class for running a web server with web services import javax. xml. ws. Endpoint; // class of our web service import ru. javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher ( public static void main (String... args) ( // start the web server on port 1986 // and to the address specified in the first argument, // start the web service passed in the second argument Endpoint. publish( "http://localhost:1986/wss/hello", new HelloWebServiceImpl () ) ; ) ) Now let's run this class by clicking Shift+F10. Nothing will appear in the console, but the server is running. You can verify this by typing the line http://localhost:1986/wss/hello?wsdl in your browser. The page that opens, on the one hand, proves that we have a web server (http://) running on port 1986 on our computer (localhost), and, on the other hand, shows a WSDL description of our web service. If you stop the application, the description will become unavailable, as will the web service itself, so we won’t do this, but move on to writing the client.

Client

In the project folder src Let's create a package ru.javarush.client , and in it the HelloWebServiceClient class with the main method: package ru. javarush. client; // needed to get wsdl description and through it // reach the web service itself import java. net. URL; // this exception will occur when working with a URL object import java. net. MalformedURLException; // classes to parse xml with wsdl description // and reach the service tag in it import javax. xml. namespace. QName; import javax. xml. ws. Service; // interface of our web service (we need more) import ru. javarush. ws. HelloWebService; public class HelloWebServiceClient ( public static void main (String args) throws MalformedURLException ( // create a link to wsdl description URL url = new URL ( "http://localhost:1986/wss/hello?wsdl") ; // We look at the parameters of the next constructor in the very first tag of the WSDL description - definitions // look at the 1st argument in the targetNamespace attribute // look at the 2nd argument in the name attribute QName qname = new QName ("http://ws.javarush.ru/" , "HelloWebServiceImplService" ) ; // Now we can reach the service tag in the wsdl description, Service service = Service. create (url, qname) ; // and then up to the port tag nested in it, so that // get a link to a web service object remote from us HelloWebService hello = service. getPort(HelloWebService.class); // Hooray! You can now call the remote method System. out. println (hello. getHelloString ( "JavaRush" ) ) ; ) ) I gave maximum comments on the code in the listing. I have nothing to add, so let’s run (Shift+F10). We should see the text in the console: Hello, JavaRush! If you didn’t see it, then you probably forgot to start the web service.

Conclusion

This topic provided a brief excursion into web services. Once again, I will say that much of what I wrote is my guess as to how it works, and therefore you should not trust me too much. I would be grateful if knowledgeable people correct me, because then I will learn something. UPD.

The topic title is really a question, because... I myself don’t know what it is and for the first time I will try to work with it within the framework of this article. The only thing I can guarantee is that the code presented below will work, but my phrases will only be assumptions and guesses about how I myself understand all this. So, let's go...

Introduction

We need to start with why the concept of web services was created. By the time this concept appeared in the world, technologies already existed that allowed applications to interact at a distance, where one program could call some method in another program, which could be launched on a computer located in another city or even country. All this is abbreviated as RPC (Remote Procedure Calling). Examples include CORBA technologies, and for Java - RMI (Remote Method Invoking). And everything seems to be good in them, especially in CORBA, because... You can work with it in any programming language, but something was still missing. I believe that the disadvantage of CORBA is that it works through some of its own network protocols instead of simple HTTP, which will fit through any firewall. The idea of ​​the web service was to create an RPC that would be inserted into HTTP packets. Thus began the development of the standard. What are the basic concepts of this standard:
  1. SOAP. Before calling a remote procedure, you need to describe this call in an XML file in SOAP format. SOAP is simply one of the many XML markups that are used in web services. Everything we want to send somewhere via HTTP is first converted into an XML SOAP description, then stuffed into an HTTP packet and sent to another computer on the network via TCP/IP.
  2. WSDL. There is a web service, i.e. a program whose methods can be called remotely. But the standard requires that this program be accompanied by a description that says that “yes, you’re right - this is really a web service and you can call such and such methods from it.” This description is represented by another XML file, which has a different format, namely WSDL. Those. WSDL is just an XML file describing a web service and nothing more.
Why so briefly you ask? Can't you be more specific? It’s probably possible, but to do this you’ll have to turn to books such as T. Mashnin, “Java Web Services.” There, over the first 200 pages, there is a detailed description of each tag of the SOAP and WSDL standards. Is it worth doing? In my opinion, no, because... all this is created automatically in Java, and you only need to write the contents of the methods that are supposed to be called remotely. So, an API such as JAX-RPC appeared in Java. If anyone doesn't know, when they say that Java has such and such an API, it means that there is a package with a set of classes that encapsulate the technology in question. JAX-RPC evolved over time from version to version and eventually became JAX-WS. WS obviously stands for WebService and you might think that this is simply a renaming of RPC as a popular buzzword these days. This is not true, because Now web services have moved away from the original idea and allow you not only to call remote methods, but also to simply send document messages in SOAP format. I don’t know why this is needed yet; it’s unlikely that the answer here will be “just in case it’s needed.” I myself would like to learn from more experienced comrades. And lastly, then JAX-RS appeared for so-called RESTful web services, but this is the topic of a separate article. The introduction can end here, because... Next we will learn to work with JAX-WS.

General approach

In web services there is always a client and a server. The server is our web service and is sometimes called the endpoint (as in, the end point where SOAP messages from the client reach). We need to do the following:
  1. Describe the interface of our web service
  2. Implement this interface
  3. Launch our web service
  4. Write a client and remotely call the desired web service method
You can launch a web service in different ways: either describe a class with the main method and launch the web service directly as a server, or deploy it to a server like Tomcat or any other. In the second case, we ourselves do not launch a new server and do not open another port on the computer, but simply tell the Tomcat servlet container that “we have written web service classes here, please publish them so that everyone who contacts you can use our use the web service." Regardless of the method of launching the web service, we will have the same client.

Server

Let's launch IDEA and create a new project Create New Project. Let's indicate the name HelloWebService and press the button Next, then button Finish. In folder src let's create a package ru.javarush.ws. In this package we will create the HelloWebService interface: package ru. javarush. ws; // these are annotations, i.e. a way to mark our classes and methods, // as related to web service technology import javax. jws. WebMethod; import javax. jws. WebService; import javax. jws. soap. SOAPBinding; // we say that our interface will work as a web service@WebService // we say that the web service will be used to call methods@SOAPBinding (style = SOAPBinding. Style. RPC) public interface HelloWebService ( // we say that this method can be called remotely@WebMethod public String getHelloString(String name) ; ) In this code, the WebService and WebMethod classes are so-called annotations and do nothing except mark our interface and its method as a web service. The same applies to the SOAPBinding class. The only difference is that SOAPBinding is an annotation with parameters. In this case, the style parameter is used with a value indicating that the web service will work not through document messages, but as a classic RPC, i.e. to call a method. Let's implement our interface logic and create a HelloWebServiceImpl class in our package. By the way, I note that ending a class with Impl is a convention in Java, according to which the implementation of interfaces is so designated (Impl - from the word implementation, i.e. implementation). This is not a requirement and you are free to name the class whatever you want, but good manners require it: package ru. javarush. ws; // the same annotation as when describing the interface, import javax. jws. WebService; // but here it is used with the endpointInterface parameter, // indicating the full name of the interface class of our web service@WebService(endpointInterface= "ru.javarush.ws.HelloWebService") public class HelloWebServiceImpl implements HelloWebService ( @Override public String getHelloString (String name) ( // just return the greeting return "Hello, " + name + "!" ; ) ) Let's launch our web service as an independent server, i.e. without the participation of any Tomcat and application servers (this is a topic for a separate discussion). To do this, in the project structure in the folder src Let's create a package ru.javarush.endpoint, and in it we will create a HelloWebServicePublisher class with the main method: package ru. javarush. endpoint; // class for running a web server with web services import javax. xml. ws. Endpoint; // class of our web service import ru. javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher ( public static void main (String... args) ( // start the web server on port 1986 // and to the address specified in the first argument, // start the web service passed in the second argument Endpoint. publish( "http://localhost:1986/wss/hello", new HelloWebServiceImpl () ) ; ) ) Now let's run this class by clicking Shift+F10. Nothing will appear in the console, but the server is running. You can verify this by typing the line http://localhost:1986/wss/hello?wsdl in your browser. The page that opens, on the one hand, proves that we have a web server (http://) running on port 1986 on our computer (localhost), and, on the other hand, shows a WSDL description of our web service. If you stop the application, the description will become unavailable, as will the web service itself, so we won’t do this, but move on to writing the client.

Client

In the project folder src Let's create a package ru.javarush.client , and in it the HelloWebServiceClient class with the main method: package ru. javarush. client; // needed to get wsdl description and through it // reach the web service itself import java. net. URL; // this exception will occur when working with a URL object import java. net. MalformedURLException; // classes to parse xml with wsdl description // and reach the service tag in it import javax. xml. namespace. QName; import javax. xml. ws. Service; // interface of our web service (we need more) import ru. javarush. ws. HelloWebService; public class HelloWebServiceClient ( public static void main (String args) throws MalformedURLException ( // create a link to wsdl description URL url = new URL ( "http://localhost:1986/wss/hello?wsdl") ; // We look at the parameters of the next constructor in the very first tag of the WSDL description - definitions // look at the 1st argument in the targetNamespace attribute // look at the 2nd argument in the name attribute QName qname = new QName ("http://ws.site/" , "HelloWebServiceImplService" ) ; // Now we can reach the service tag in the wsdl description, Service service = Service. create (url, qname) ; // and then up to the port tag nested in it, so that // get a link to a web service object remote from us HelloWebService hello = service. getPort(HelloWebService.class); // Hooray! You can now call the remote method System. out. println (hello. getHelloString ( "JavaRush" ) ) ; ) ) I gave maximum comments on the code in the listing. I have nothing to add, so let’s run (Shift+F10). We should see the text in the console: Hello, JavaRush! If you didn’t see it, then you probably forgot to start the web service.

Conclusion

This topic provided a brief excursion into web services. Once again, I will say that much of what I wrote is my guess as to how it works, and therefore you should not trust me too much. I would be grateful if knowledgeable people correct me, because then I will learn something. UPD.

Today WEB services are used almost everywhere - they provide us with information about plane and train flights, exchange rates and weather. It is not surprising that 1C also has the ability to create its own WEB services, allowing it to act as both a supplier and a consumer. This mechanism is built into the 1C:Enterprise 8.3 platform and developers can even add their own objects of the WEB services type to the standard configuration. Their architecture is built on a set of services that allow you to exchange information with other software.

Creating a 1C web service

One of the main advantages of 1C WEB services is the absence of the need to provide direct access to information security data. A correctly configured 1C web service allows other applications to use functions from the outside. In such cases, the function itself should determine the right to use data according to the specified parameters according to the rules prescribed by the developer.

How to create a web service in 1C?

In order for a certain function of the 1C system to become available to external software, it is necessary to perform the following algorithm of actions:

  1. Go to the configuration and add a WEB service object in a certain branch of the tree;
  2. Describe all the operations that our functionality can perform. The description of functions is carried out in the module in the built-in 1C language;
  3. Add a description of the parameters of the web service functions. Please note that the data types are described taking into account the existing types of the XDTO mechanism introduced in the platform version 8.1;
  4. Publish the created WEB service on the server. The mechanism built into the 1C platform supports the following standards:
  • SSL/TLS
  • WS-I BP

An example of creating a simple WEB service

To most clearly demonstrate the operation of the WEB services mechanism, let's create an example - a functionality that determines the length of the entered string. The software will pass a string as a request parameter, and the function described in 1C will return the number of characters. When creating, you need to remember that publishing this mechanism will make it possible for various software to access it. Since not every software is capable of accepting the Cyrillic alphabet, we will name configuration objects using Latin characters.

Open the configurator, find the “WEB services” branch in the tree and add a new service “wa_LengthString”. You also need to add a new operation on the “Operations” tab. Let's call it “CalcLengthString”, specify the return value type in the properties - int or integer and create the “InputString” parameter inside it. We leave the value type as string.

Now you need to register the action of the CalcLengthString function in the WEB service module. To do this, open the properties of the created function and click the button in the form of a magnifying glass on the right, next to the “Procedure name” input field. 1C will automatically create a function in our WEB service module and open it so that we can describe the CalcLengthString action. Let's take advantage of this and write the action of the function - determining the length of the input string.


In fact, this completes the creation of a simple WEB service. Now it is necessary to “put” this service into the public domain so that third-party software or other 1C systems can use this functionality.

In order for us to be able to publish the created web service with its functionality, we need to have access to the site. Before we start publishing the service, we need to check the file name in the properties of the created wa_LengthString module. It should be clear, simple and have the extension “1cws”.


Now it's time to publish the WEB service we created on the server. This feature appeared in platform version 8.3 and many companies have already realized the full benefits of this functionality. In order to start publishing, you need to open the “Administration/Publishing on a web server...” form in the configurator.


In the window that opens, we need to configure 1C Web services and fill in certain fields:

  • Name. Designates the folder on the web server in which the description of our web service will be stored. Be careful about cases, as sometimes servers distinguish between large and small case characters;
  • Web server. You must select a server from those installed on your computer;
  • Catalog. You must select the path to the folder where the web server data for setting up the connection is stored. Only Latin letters are used;
  • Two signs of the Boolean type. The first one will be useful to us if we need to configure access to the configuration via a web client. In order to publish a 1C service, you need to check the second box.

All that remains is to check that the desired WEB service has the checkbox checked in the first column and click on “Publish”.


Since this mechanism is still quite new, you may encounter an error like “An error occurred while performing a file operation...”. In this case, you just need to click “Publish” again. In most cases, this will help and you will see a message indicating that the web service has been published.

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

In response to such an address request, the browser must display the structure of the XML file. If you see a blank page, an error, or strange characters (encoding problems), then you need to check all the steps again. It is also a good idea to make sure that the server is configured correctly and you have access to it. After successful publication, the 1C WEB service will be able to be used by third-party applications.


Keywords: web service, web service, SOAP, WSDL, ws link

Disclaimer and terms of use

All trademarks accidentally mentioned in this article belong to their respective owners.
This article is published under a Creative Commons Attribution-Share Alike 3.0 Unported License. http://creativecommons.org/licenses/by-sa/3.0/

Another disclaimer (after many times)

The 1C:Enterprise 8 platform is constantly evolving. Therefore, the code presented in this article will generate an error in the latest versions of the platform. This happens, in particular, due to the fact that the order of calling methods of a web service proxy object has changed: for example, complex objects must be explicitly converted to an XDTO Object of the appropriate type, using the Factory of the corresponding service. You can read about this on our forum or in the book “1C:Enterprise Integration Technologies” http://v8.1c.ru/metod/books/book.jsp?id=288

Introduction

When a new version of a software product appears, naturally, first of all, you want to understand what’s new in it. In the case of 1C:Enterprise 8.1, web services became such a new “feature” for me. A lot has been written and said about web services, since this technology has existed for quite a long time by computer standards. Therefore, I will not repeat myself; I refer everyone to Yandex for information. I will only say that with the release of the new edition of the 1C:Enterprise 8.1 platform, 1Snikov has the opportunity to create and use web services technology, being, so to speak, in their native environment. In this article I want to show how to use external web services in your developments.

For those who are completely “out of the loop”: about web services “at your fingertips”

OK, specially for you I’ll try to tell you a little about what a web service is and why exactly This It seemed to me such a “delicious” innovation of the platform. Perhaps you know about COM technology or heard something about OLE? Sooner or later, any individual worker will come across this technology (especially if you need to quickly transfer some directory “Employees”, and the HR department, anticipating the need to drive in all 1,500 employees again, is ready to hang you on the first suitable nail that comes along).
Yes, so, at the heart of COM technology is the idea of possibilities calling program code (and accessing data) of one application from another application. Moreover, possibilities do this not at the level of individual procedures and functions, but by getting at the disposal objects another application. When using OLE, we create an object in our application that is " representative"or, if you prefer, " wrapper"of some object of the application with which we want to interact (the so-called "OLE object" or "COM object"). Through this "wrapper" object, the properties and methods of the object of another application become available to us, and only those of which the developer Togo Apps allowed us to use by publishing them in the description interface. (Well, I didn’t want to get into the weeds, but there’s no other way...)
Now let's imagine that exactly the same the application is located on another computer, and not even on the local network (DCOM, CORBA and other abstruse abbreviations handle such cases well), but somewhere far, far away on the Internet. This is where web services come onto the scene (also complete with abstruse acronyms: SOAP, WSDL, etc.), which allow you to perform a similar “trick” in this case: i.e. receive data and manipulate objects from an application running on a computer on the other side of the Internet.
Under " external"by web service I mean a web service provided to some supplier service (i.e. not our application.) Accordingly, by “internal” - the web service that we will provide from, or, more precisely, based our application. When using external web services, we must understand that although the “wrapper” object is created in our “local” application, the “executing code” of this object is located, perhaps, on the other side of the Globe. At the same time, the exchange between us And them takes place on the now ubiquitous XML, with its well-known “pros” (versatility and structure) and “cons” (bloat), and the good old http is used as the “transmission line”.
Yes, and don’t forget about Internet traffic! Moreover, in the case of external web services, most of it will be on incoming component.
Everything else is in Yandex. Let's move on...

Where are the legs from, i.e. wings grow

Having rummaged through Yandex, I found a wonderful web service from the Aeroflot company, which allows you to receive information about the arrival and departure of aircraft in real time, and decided to make a kind of “Airport Display” in 1C:Enterprise. The service itself lives here: http://webservices.aeroflot.ru/desc_flightinfo.asp

He said: "Let's go!"

To begin with, I created an empty configuration of "1C:Enterprise 8.1" (at the time of writing I had platform version 8.1.5.123 at my disposal). Then I added a new object of type WS-link to my configuration. When prompted to enter the URL of the imported WSDL, I entered a link to the WSDL file, which is listed on the service page: http://webservices.aeroflot.aero/flightstatus.wsdl (The WSDL file is a description of the web service. For details, go to Yandex ), and proudly named the created facility “Aeroflot”. By double-clicking on this object, I got a tree with the structure of a web service.

This tree represents a “portrait” of the web service, as 1Ska sees it. The most interesting thing is in the "Web services" branch: this names And ports web services (in fact, a WSDL file can describe not one, but several web services, then each web service will have its own branch), and are listed methods web service. These are the very “strings”, by pulling which you can give yourself access to the data that the web service provides. The "Data Model" branch contains a description of the data type libraries that are used by the web service.
A brief summary of how to use the web service can usually be found in the same place as the link to the WSDL file. In the case of Aeroflot, this is the page http://webservices.aeroflot.aero/flightstatus.asmx

"Now takeoff, now landing..."

To work with the web service, I added “Departures Display” processing to the configuration, and in it - one form, which I designated as the main one. On the form I placed the selection field "Airport Selection", the "Flight Date" input field, the "Tableboard Panel" panel with two pages "Arrivals" and "Departures", while I unchecked the "Distribute across pages" flag in the panel properties, and the "Tableboard" table field ".
Interaction with a web service occurs on the “request-response” principle, and a special intermediary object is created for the web service. Therefore, I added the “ServiceAeroflot” form details of a custom type.
If you carefully read the description of the service, you can see that the web service provides data on arrivals and departures through calls to the Arrival and Departure methods, respectively. In this case, both methods take the airport code and the desired date as parameters. In addition, the web service provides the ability to obtain a list of airports for which data is available in the system. The following scenario of interaction with a web service is quite obvious:
1. Get a list of airports;
2. Select the desired airport and date;
3. Get data on arrivals or departures;
But before accessing the web service, you need to initialize an intermediary object (such as WSProxy), which is what I did in the form opening handler:
ServiceAeroflot=WSLinks.Aeroflot.CreateWSProxy(" http: //www.aeroflot.ru/", "FlightStatus", "FlightStatusSoap");
The first parameter is the URI of the web service namespace. You can find it out by opening the properties of the web service in the WS link tree. The second and third parameters transmit the name and port of the web service, respectively.
(do not confuse the concepts of “name”, “port”, “proxy”, etc. as applied to web services with the more familiar concepts of the TCP/IP protocol. If there is a correspondence between them, it is rather semantic. In the general case you need to understand that, for example, a web service port and a TCP port are completely different things).
Thus, I initialized the Aeroflot Service object of the WSProxy type, which is essentially a “wrapper” of the web service. Through it, I can access web service methods as “native” methods of the platform.
First of all, I received a list of airports and filled in the list of the "Select Airport" selection field:

SelectionList=FormElements.AirportSelection.SelectionList; SelectionList.Clear(); AirportList=Aeroflot Service.AirportList().GetList("list "); TotalAirports=ListAirports.Count(); For ui=0 to TotalAirports-1 Cycle Airport=ListAirports.Get(ies); SelectionList.Add(Airport.code, ""+Airport.city+" : "+Airport.name); EndCycle;
Here we need a small comment on the construction of Airport List = ServiceAeroflot.AirportList().GetList("list");
The fact is that the values ​​returned by web service methods are represented in the platform by objects of the XDTO Object type. Since the topic of XDTO technology is beyond the scope of this article, I will only say that for transformations this object into a list (which it is), I called its GetList() method. The rest of the code is quite obvious, including the names of the fields of the Airport structure, which I found on the web service description page.
Now you can run the configuration and make sure that the selection field list is populated with airport names:

"Departure day, arrival day..."

Now I have almost everything ready to make my scoreboard function. All that remains is to “paint it and throw it away” :) That’s what I’ll do:

Procedure FillTableboard(Arrival=True) TableTableboard.Columns.Clear(); TableTableboard.Columns.Add("Flight Code", "Flight Code"); TableTableboard.Columns.Add(" Airline code", "Airline"); TableTable.Columns.Add("FlightNumber", "Number"); TableTable.Columns.Add(" AirportTransit", "Airport transit"); TableTable.Columns.Add("Airport", "Airport"+?(Arrivals,"departures,","arrivals")); TableTable.Columns.Add(" TimeSchedule", "On schedule"); TableTableboard.Columns.Add(" TimePlanned", "Planned"); TableTableboard.Columns.Add(" TimeActual", "Actual"); TableTable.Columns.Add("Calculated Time", "Calculated"); TableTable.Columns.Add("Landing Time", ?(Arrival,"Landing","Takeoff")); TableTable.Columns. Add("Combined Flight", "Combined Flight"); TableTable.Columns.Add("Status", "Status"); If Not Arrival Then TableTable.Columns.Add("Registration", "Registration"); TableTable.Columns .Add("Landing", "Landing"); EndIf; Form Elements. Scoreboard Table. Create Columns(); Form Elements. Scoreboard Table. Columns. Flight Code. Visibility = False; If Not Arrival Then Form Elements. Scoreboard Table. Columns. Estimated Time. Visibility = False; EndIf; If Arrival Then Data=Aeroflot Service.Arrival(Airport Selection, Flight Date).Get List("list "); Otherwise Data=Aeroflot Service.Departure(Airport Selection, Flight Date).Get List("list "); EndIf; Total Records=Data.Number( ); For ii=0 for 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=Record.real; NewLine.UnionFlight=Record.union_flight_no; NewRow.Status=Record.status; If Not Arrival Then NewLine.Registration=Record.is_check; NewLine.Landing = Entry.is_board; endIf; EndCycle; End of Procedure

In order to check how it all works, I added an “Update” button with a corresponding picture to the form’s command panel, and in its handler I wrote the following:

Procedure CommandPanel1 Update(Button) FillTableboard(FormElements.TableboardPanel.CurrentPage=FormElements.TableboardPanel.Pages.Arrivals); End of Procedure
I save, run, select, click, get:

Afterword

Surprisingly, after the article was written and published, it turned out that the respected ZAV had already published a similar example on IT-Land: http://itland.ru/biblio/detail.php?ID=1060
In order to avoid possible accusations of plagiarism, I strongly recommend that you read this article too and compare the approaches of the authors.