使用 Meta-Data (`multipart/form-data`) 将文件上传到 ColdFusion 11 REST 服务
Upload File with Meta-Data (`multipart/form-data`) to ColdFusion 11 REST Service
如何在 ColdFusion 11 REST 服务中访问通过文件上传(使用 enctype="multipart/form-data"
)发送的 meta-data(表单数据)?
模拟一个简单的服务:
component
restpath = "test"
rest = true
{
remote void function upload(
required numeric id restargsource = "Path",
required any document restargsource = "Form",
required string title restargsource = "Form"
)
httpmethod = "POST"
restpath = "{id}/"
produces = "application/json"
{
if ( FileExists( document ) )
restSetResponse({
"status" = 201,
"content" = {
"id" = id,
"title" = title,
"size" = GetFileInfo( document ).size
}
});
else
restSetResponse({
"status" = 400,
"content" = "Nothing uploaded"
});
}
}
和一个简单的 HTML 文件来测试它:
<!DOCTYPE html>
<html>
<body>
<form method="post"
action="http://localhost/rest/TestService/test/1/"
enctype="multipart/form-data">
<input type="text" name="title" value="File Title" /><br />
<input type="file" name="document" /><br />
<button type="submit">Submit</button>
</form>
</body>
</html>
然后服务 returns 一个 500
HTTP 状态代码和 JSON 响应:
{"Message":"The DOCUMENT parameter to the upload function is required but was not passed in."}
检查 HTTP 请求 headers 显示两个字段都已传入,但服务未接收到它们。
注释掉 HTML 表单中的 enctype
属性(因此它使用 application/x-www-form-urlencoded
的默认编码)然后服务 returns a 400
HTTP 状态代码和响应 Nothing uploaded
.
如何解决?
为了彻底混淆请求数据填充 FORM
变量,但是,即使函数参数声明 restargsource="form"
,当 enctype
不是 application/x-www-form-urlencoded
.
Adobe 的 Getting started with RESTful web services in ColdFusion 文章证实了这一点:
Form parameters:
In many scenarios, you must process data that you enter in the form in a REST service. You can use this data to make a new entry ( POST
) or update an existing record ( PUT
) in the database. If you use form fields, set restargsource
to form
. This extracts the data present in the request and makes it available for further processing. Also, you must set the content-type header to application/x-www-form-urlencoded
when sending data as form fields.
但是,可以通过将使用 restargsource="form"
的参数更改为明确限定在 form
变量范围内的参数来解决。
所以,像这样修改服务:
component
restpath = "test"
rest = true
{
remote void function upload(
required numeric id restargsource = "Path"
)
httpmethod = "POST"
restpath = "{id}/"
produces = "application/json"
{
param name="form.document" type="string";
param name="form.title" type="string";
if ( FileExists( form.document ) )
restSetResponse({
"status" = 201,
"content" = {
"id" = id,
"title" = form.title,
"size" = GetFileInfo( form.document ).size
}
});
else
restSetResponse({
"status" = 400,
"content" = "Nothing uploaded"
});
}
}
如何在 ColdFusion 11 REST 服务中访问通过文件上传(使用 enctype="multipart/form-data"
)发送的 meta-data(表单数据)?
模拟一个简单的服务:
component
restpath = "test"
rest = true
{
remote void function upload(
required numeric id restargsource = "Path",
required any document restargsource = "Form",
required string title restargsource = "Form"
)
httpmethod = "POST"
restpath = "{id}/"
produces = "application/json"
{
if ( FileExists( document ) )
restSetResponse({
"status" = 201,
"content" = {
"id" = id,
"title" = title,
"size" = GetFileInfo( document ).size
}
});
else
restSetResponse({
"status" = 400,
"content" = "Nothing uploaded"
});
}
}
和一个简单的 HTML 文件来测试它:
<!DOCTYPE html>
<html>
<body>
<form method="post"
action="http://localhost/rest/TestService/test/1/"
enctype="multipart/form-data">
<input type="text" name="title" value="File Title" /><br />
<input type="file" name="document" /><br />
<button type="submit">Submit</button>
</form>
</body>
</html>
然后服务 returns 一个 500
HTTP 状态代码和 JSON 响应:
{"Message":"The DOCUMENT parameter to the upload function is required but was not passed in."}
检查 HTTP 请求 headers 显示两个字段都已传入,但服务未接收到它们。
注释掉 HTML 表单中的 enctype
属性(因此它使用 application/x-www-form-urlencoded
的默认编码)然后服务 returns a 400
HTTP 状态代码和响应 Nothing uploaded
.
如何解决?
为了彻底混淆请求数据填充 FORM
变量,但是,即使函数参数声明 restargsource="form"
,当 enctype
不是 application/x-www-form-urlencoded
.
Adobe 的 Getting started with RESTful web services in ColdFusion 文章证实了这一点:
Form parameters:
In many scenarios, you must process data that you enter in the form in a REST service. You can use this data to make a new entry (
POST
) or update an existing record (PUT
) in the database. If you use form fields, setrestargsource
toform
. This extracts the data present in the request and makes it available for further processing. Also, you must set the content-type header toapplication/x-www-form-urlencoded
when sending data as form fields.
但是,可以通过将使用 restargsource="form"
的参数更改为明确限定在 form
变量范围内的参数来解决。
所以,像这样修改服务:
component
restpath = "test"
rest = true
{
remote void function upload(
required numeric id restargsource = "Path"
)
httpmethod = "POST"
restpath = "{id}/"
produces = "application/json"
{
param name="form.document" type="string";
param name="form.title" type="string";
if ( FileExists( form.document ) )
restSetResponse({
"status" = 201,
"content" = {
"id" = id,
"title" = form.title,
"size" = GetFileInfo( form.document ).size
}
});
else
restSetResponse({
"status" = 400,
"content" = "Nothing uploaded"
});
}
}