使用 REST::Client 的 perl 多部分请求
perl multipart request using REST::Client
我正在使用 Perl 的 REST::Client 进行多部分 POST 请求:
#! /usr/bin/perl
use REST::Client;
use JSON;
$file = 'output.csv';
$headers = {'Content-Type' => 'multipart/form-data', 'Authorization' => 'Bearer '.$token.''};
$client = REST::Client->new();
$req = '{"sessionId" => '.$sessionId.' , "content" => ["file" => ['.$file.']]}';
$client->setHost(<host>);
$client->POST( '/api/test',$req, $headers);
$response = from_json($client->responseContent());
REST api 如下:
@PostMapping("/test")
@Timed
public Response<Map<String, Object>> test(@RequestParam("file") MultipartFile file,
@RequestParam("sessionId") Long sessionId,
HttpServletRequest request) throws URISyntaxException {
}
当我 运行 脚本出现以下错误时:
Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found]
我是 perl 的新手,语法或其他方面有什么问题吗?
REST::Client 期望您制作完整的消息 body,而您没有这样做。实际上,您不应该尝试手动构建请求(甚至 JSON)。我从你的代码中怀疑你真的不应该提出多部分请求,但我必须查看 API 文档才能说明这一点。
这是 Mojo::UserAgent 中的类似任务。我没有尝试发送消息 body,而是使用 Mojo 计算出的数据结构发出请求:
use Mojo::UserAgent;
use v5.10;
my $ua = Mojo::UserAgent->new;
my $url ='http://httpbin.org/post';
my $session_id = 'deadbeef';
my $filename = 'upload_file.csv';
my $tx = $ua->post(
$url,
form => {
session => $session_id,
some_file => {
file => $filename,
},
},
);
say "Request:\n", $tx->req->to_string;
say "Response:\n", $tx->result->to_string;
将此发送到 httpbin 是一种方便的测试方法。输出显示 header 和 multipart 内容自动为您发生:
Request:
POST /post HTTP/1.1
User-Agent: Mojolicious (Perl)
Content-Length: 208
Content-Type: multipart/form-data; boundary=75OiX
Accept-Encoding: gzip
Host: httpbin.org
--75OiX
Content-Disposition: form-data; name="session"
deadbeef
--75OiX
Content-Disposition: form-data; name="some_file"; filename="upload_file.csv"
upload,this,file
here's,another,line
--75OiX--
Response:
HTTP/1.1 200 OK
Connection: keep-alive
Access-Control-Allow-Credentials: true
Date: Sat, 25 Apr 2020 03:44:04 GMT
Access-Control-Allow-Origin: *
Content-Length: 516
Content-Type: application/json
Server: gunicorn/19.9.0
{
"args": {},
"data": "",
"files": {
"some_file": "upload,this,file\nhere's,another,line\n"
},
"form": {
"session": "deadbeef"
},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "208",
"Content-Type": "multipart/form-data; boundary=75OiX",
"Host": "httpbin.org",
"User-Agent": "Mojolicious (Perl)",
"X-Amzn-Trace-Id": "Root=1-5ea3b204-12cfdb84b9c9c504da559e80"
},
"json": null,
"origin": "199.170.132.3",
"url": "http://httpbin.org/post"
}
我在 Mojolicious Web Clients 中有更多示例。
我正在使用 Perl 的 REST::Client 进行多部分 POST 请求:
#! /usr/bin/perl
use REST::Client;
use JSON;
$file = 'output.csv';
$headers = {'Content-Type' => 'multipart/form-data', 'Authorization' => 'Bearer '.$token.''};
$client = REST::Client->new();
$req = '{"sessionId" => '.$sessionId.' , "content" => ["file" => ['.$file.']]}';
$client->setHost(<host>);
$client->POST( '/api/test',$req, $headers);
$response = from_json($client->responseContent());
REST api 如下:
@PostMapping("/test")
@Timed
public Response<Map<String, Object>> test(@RequestParam("file") MultipartFile file,
@RequestParam("sessionId") Long sessionId,
HttpServletRequest request) throws URISyntaxException {
}
当我 运行 脚本出现以下错误时:
Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found]
我是 perl 的新手,语法或其他方面有什么问题吗?
REST::Client 期望您制作完整的消息 body,而您没有这样做。实际上,您不应该尝试手动构建请求(甚至 JSON)。我从你的代码中怀疑你真的不应该提出多部分请求,但我必须查看 API 文档才能说明这一点。
这是 Mojo::UserAgent 中的类似任务。我没有尝试发送消息 body,而是使用 Mojo 计算出的数据结构发出请求:
use Mojo::UserAgent;
use v5.10;
my $ua = Mojo::UserAgent->new;
my $url ='http://httpbin.org/post';
my $session_id = 'deadbeef';
my $filename = 'upload_file.csv';
my $tx = $ua->post(
$url,
form => {
session => $session_id,
some_file => {
file => $filename,
},
},
);
say "Request:\n", $tx->req->to_string;
say "Response:\n", $tx->result->to_string;
将此发送到 httpbin 是一种方便的测试方法。输出显示 header 和 multipart 内容自动为您发生:
Request:
POST /post HTTP/1.1
User-Agent: Mojolicious (Perl)
Content-Length: 208
Content-Type: multipart/form-data; boundary=75OiX
Accept-Encoding: gzip
Host: httpbin.org
--75OiX
Content-Disposition: form-data; name="session"
deadbeef
--75OiX
Content-Disposition: form-data; name="some_file"; filename="upload_file.csv"
upload,this,file
here's,another,line
--75OiX--
Response:
HTTP/1.1 200 OK
Connection: keep-alive
Access-Control-Allow-Credentials: true
Date: Sat, 25 Apr 2020 03:44:04 GMT
Access-Control-Allow-Origin: *
Content-Length: 516
Content-Type: application/json
Server: gunicorn/19.9.0
{
"args": {},
"data": "",
"files": {
"some_file": "upload,this,file\nhere's,another,line\n"
},
"form": {
"session": "deadbeef"
},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "208",
"Content-Type": "multipart/form-data; boundary=75OiX",
"Host": "httpbin.org",
"User-Agent": "Mojolicious (Perl)",
"X-Amzn-Trace-Id": "Root=1-5ea3b204-12cfdb84b9c9c504da559e80"
},
"json": null,
"origin": "199.170.132.3",
"url": "http://httpbin.org/post"
}
我在 Mojolicious Web Clients 中有更多示例。