Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 1 августа 2010 в 00:41.
Категории: Delphi в Web.


Иногда требуется одним POST-запросом отправить на сервер несколько разных по составу и содержанию документов. К примеру, такие действия требуются, когда Вы загружаете на сервер Google какой-либо документ, который должен содержать какую-либо мета-информацию (язык на которой необходимо перевести документ, сведения об авторе и т.д.). В этом случае ваш запрос должен одновременно содержать информацию двух типов: XML с мета-данными и данные отправляемого файла. Как это сделать рассмотрим на примере Google Documents List API.

Для работы нам понадобится компонен GoogleLogin, последнюю рабочуюю версию которого Вы можете скачать здесь и, собственно, сама библиотека Synapse. Для обработки XML воспользуемся возможностями NativeXML.
Итак, пишем маленькое приложение, которое загружает на сервер Google документ и в качестве мета-информации отправляет название документа. Размещаем на главной форме компонент GoogleLogin и несколько дополнительных компонентов как показано на рисунке:

Главная форма приложения

и пишем приложение по частям.

1. Авторизация в сервисе "Документы Google"

На данный момент, используя компонент GoogleLogin узнать о результате авторизации можно только через его событие OnAutorization. Поэтому на событие OnClick кнопки "Логин" пишем:

procedure TForm6.Button1Click(Sender: TObject);
begin
  with GoogleLogin1 do
    begin
      Email:=Edit1.Text;
      Password:=Edit2.Text;
      Service:=writely;//идентификатор сервиса гуглодоков
      AccountType:=atHOSTED_OR_GOOGLE;
      Login();
    end;
end;

А в обработчики события компонента проверяем результат (без обработки каптчи):

procedure TForm6.GoogleLogin1Autorization(const LoginResult: TLoginResult;
  Result: TResultRec);
begin
  if LoginResult=lrOk then
    Edit3.Text:=Result.Auth
  else
   Edit3.Text:=Result.LoginStr;
Button2.Enabled:=LoginResult=lrOk;
Button3.Enabled:=LoginResult=lrOk;
end;

После того, как авторизация получена можно отправлять документ на сервер.

2. Формирование запроса и его отправка

Вначале напишем код, который будет составлять XML-документ. Документ должен быть следующего содержания:

<code>
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005">
  <category scheme="http://schemas.google.com/g/2005#kind"
      term="http://schemas.google.com/docs/2007#document"/>
  <title>%s</title>
</entry>
</code>

Так как изменяться в документе будет всего одна строка - содержимое тега Title, то я просто сохранил этот документ в файл xml.txt и буду этот файл при необходимости изменять. В итоге для составления правильного XML-содержимого запроса сделать необходимо не так уж и много:

var
  Form6: TForm6;
  XMLStream: TMemoryStream;;
...
procedure TForm6.FormCreate(Sender: TObject);
begin
  XMLStream:=TMemoryStream.Create;
end;
 
function TForm6.GetXML(const DocTitle: string): string;
begin
  var XMLDoc: TNativeXML;
begin
  XMLStream.Clear;//очистили поток
  XMLDoc:=TNativeXML.Create;
  XMLDoc.LoadFromFile(ExtractFilePath(Application.ExeName)+'xml.txt');
  XMLDoc.Root.NodeByName('title').ValueAsString:=Edit5.Text;//замненили название документа
  XMLDoc.SaveToStream(XMLStream);//сохранили данные в поток
FreeAndNil(XMLDoc);
end;
 
procedure TForm6.FormDestroy(Sender: TObject);
begin
  FreeAndNil(XMLStream)
end;

Теперь составляем запрос и осуществляем отправку запроса. Для этого подключаем в uses модуль httpsend:

procedure TForm6.Button3Click(Sender: TObject);
Const
  CR = #$0d;
  LF = #$0a;
  CRLF = CR + LF;
var HTTP: THTTPSend;
    S:AnsiString;
    FS: TFileStream;
begin
  //получили XML
  GetXML(Edit5.Text);
 
  HTTP:=THTTPSend.Create;
  //вставляем заголовки авторизации
  HTTP.Headers.Add('GData-Version: 3.0');
  HTTP.Headers.Add('Authorization: GoogleLogin auth='+Edit3.Text);
  //определяем тип данных
  HTTP.MimeType:='multipart/related; boundary=END_OF_PART';
  HTTP.Headers.Add('Slug: '+EncodeURLElement(ExtractFileName(Edit4.Text)));
  {составляем тело запроса}
  S:='--END_OF_PART'+CRLF;
  //MIME-тип первой части документа
  S:=S+'Content-Type: application/atom+xml'+CRLF+CRLF;
  HTTP.Document.Write(PAnsiChar(S)^, Length(S));//записали строку
  //пишем в Document содержимое XML
  XMLStream.Position:=0;
  HTTP.Document.CopyFrom(XMLStream,XMLStream.Size);
  S:=CRLF+CRLF+'--END_OF_PART'+CRLF;//первая часть документа закончена
 
  {вторая часть - документ *.doc}
  S:=S+'Content-Type: application/msword'+CRLF+CRLF;
  HTTP.Document.Write(PAnsiChar(S)^, Length(S));//записали строку
  {записываем doc-файл}
  FS:=TFileStream.Create(Edit4.Text,fmOpenRead);
  FS.Position:=0;
  HTTP.Document.CopyFrom(FS,FS.Size);
  FreeAndNil(FS);
  {завершаем тело запроса}
  s := CRLF + '--END_OF_PART--' + CRLF;
  HTTP.Document.Write(PAnsiChar(S)^, Length(S));//завершили тело документа
 
  //Отправляем запрос
  if HTTP.HTTPMethod('POST','http://docs.google.com/feeds/default/private/full') then
    ShowMessage(HTTP.ResultString);
end;

В этой процедуре мы загружаем в Document (TMemoryStream) данный из двух потоков, разделяя каждую часть специальным разделителем, который, кстати сказать, может быть не только такой как показано в примере. Если отправка завершилась успешно, то в результате выполнения процедуры мы получим сообщение с текстом "201 Created" - документ успешно отправлен и создан на сервере Google.

Исходники приложения можно скачать здесь.

--------------------------------------------------------------
Продолжение бесплатной акции.
И за вчерашний день самым продуктивным блогом оказался блог "Delphi 2010". Если Вас интересуют компоненты DevExpress, причём не просто рекламная информация о том какие они замечательные, а именно трезвая оценка их работы на примерах их практического использования, то предлагаю Вам ознакомится с целой серией постов, посвященных теме использования DevExpress в Delphi.
--------------------------------------------------------------

------------------------------------------------------------
Смотрели сериал "Черная метка"? Если он вам понравился, то можете заглянуть на фан-сайт этого сериала - burn-notice.ru
------------------------------------------------------------
Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (2)

WP_Cloudy
  • Pavel пишет:

    А нету ли у Вас примера как отправить файл на определенный сайт (FTP наверное). То есть указать хост, пароль, логин, порт… В примерах, идущими вместе с Synapse так и не разобрался. С получением файла проблем нет, а вот с отправкой, пока не понятно.

  • Vlad пишет:

    Pavel, сорри, нос FTP в Synapse не работал никогда. Как-то не довелось. Если будет необходимость работы с FTP, то в блоге вы эту работу увидите :)

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник