我正在尝试通过其REST API调用Apache-TIKA。我已经能够成功上传PDF文档并通过CURL返回该文档的文本
curl -X PUT --data-binary @<filename>.pdf http://localhost:9998/tika --header "Content-type: application/pdf"
像这样翻译成INDY:
function GetPDFText(const FileName: String): String;
var
IdHTTP: TIdHTTP;
Params: TIdMultiPartFormDataStream;
begin
IdHTTP := TIdTTP.Create;
try
Params := TIdMultiPartFormDataStream.Create;
try
Params.Add('file', FileName, 'application/pdf')
Result := IdHTTP.PUT('http://localhost:9998/tika', Params);
finally
Params.Free;
end;
finally
IdHTTP.Free;
end;
end;
现在我要上传Word文档(.docx)我以为,将文件添加到Params时,我需要做的就是更改内容类型,但这似乎不会产生任何结果,尽管我没有报告任何错误。我能够获得以下CURL命令正常运行]
CURL -T <myDOCXfile>.docx http://localhost:9998/tika --header "Content-type: application/vnd.openxmlformats-officedocument.wordprocessingml.document"
如何将我的HTTP调用从CURL -X PUT修改为CURL -T?
您的实现中至少有两个问题:
CURL -X PUT
到TIdHTTP
的翻译是错误的。Accept
HTTP标头以特定格式检索提取的文本。curl -X PUT
翻译成印地语?首先,请清楚在以下情况下curl -X PUT --data-binary @<filename> <url>
与curl -T <filename> <url>
相同:
<url>
的方案是HTTP
或HTTPS
<url>
不以/
结尾因此,在您的情况下使用一种或另一种都没有关系。另请参阅curl documentation。
[其次,TIdMultiPartFormDataStream
是为与POST
动词一起使用而设计的,但是没有什么可以阻止您将其传递给TIdHTTP.Put
的,因为它是直接从TStream派生的。甚至invariant of TIdHTTP.Post
的专用TIdHTTP.Post
方法都接受TIdHTTP
:
function Post(AURL:string; ASource:TIdMultiPartFormDataStream):string;重载;
要将文件上传到服务,只需使用TIdMultiPartFormDataStream
方法作为参数,并使用TIdHTTP.Put
作为参数,同时在HTTP标头中提供要上传的文件的正确内容类型。
最后,您尝试从文档中提取纯文本,但是没有指定服务应返回的内容类型。这是通过TFileStream
HTTP标头完成的。 Accept
的默认实例的属性TIdHTTP
初始化为IdHTTP.Request.Accept
(可能因Indy版本而异)。因此,默认情况下,Tika将返回HTML格式的文本。要获取纯文本,应将其更改为'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
。
固定执行:
'text/plain; charset=utf-8'
根据uses IdGlobal, IdHTTP;
function GetDocumentText(const FileName, ContentType: string): string;
var
IdHTTP: TIdHTTP;
Stream: TIdReadFileExclusiveStream;
begin
IdHTTP := TIdHTTP.Create;
try
IdHTTP.Request.Accept := 'text/plain; charset=utf-8';
IdHTTP.Request.ContentType := ContentType;
Stream := TIdReadFileExclusiveStream.Create(FileName);
try
Result := IdHTTP.Put('http://localhost:9998/tika', Stream);
finally
Stream.Free;
end;
finally
IdHTTP.Free;
end;
end;
function GetPDFText(const FileName: string): string;
const
PDFContentType = 'application/pdf';
begin
Result := GetDocumentText(FileName, PDFContentType);
end;
function GetDOCXText(const FileName: string): string;
const
DOCXContentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
begin
Result := GetDocumentText(FileName, DOCXContentType);
end;
,它还支持发布多部分表单数据。如果您坚持使用此方法,则应在实现中将目标资源更改为Tika's documentation并切换到/tika/form
方法:
Post
当您通过function GetDocumentText(const FileName, ContentType: string): string;
var
IdHTTP: TIdHTTP;
FormData: TIdMultiPartFormDataStream;
begin
IdHTTP := TIdHTTP.Create;
try
IdHTTP.Request.Accept := 'text/plain; charset=utf-8';
FormData := TIdMultiPartFormDataStream.Create;
try
FormData.AddFile('file', FileName, ContentType); { older Indy versions: FormData.Add(...) }
Result := IdHTTP.Post('http://localhost:9998/tika/form', FormData);
finally
FormData.Free;
end;
finally
IdHTTP.Free;
end;
end;
进行Post
多部分表单数据时,Indy会自动将请求的内容类型设置为TIdHTTP
。当您'multipart/form-data; boundary=...whatever...'
(除非在执行请求之前先Put
)数据并且因此set it manually保持空白时,情况并非如此。现在,我只能猜测,当Tika看到空的内容类型时,它会退回到某种默认类型(可能是PDF),并且仍然可以从多部分请求中读取文档。