使用 FOSRestBundle 将 POST 请求主体序列化为数组
Serialize POST request body into array with FOSRestBundle
我正在尝试使用 Symfony 3 和 FOSRestBundle 制作 Rest 网络服务。
我来自 Spring + Jackson 背景,所以我正在努力做到这一点,以便您可以将对象作为请求主体传递给控制器,请求主体成为函数参数,return 对象被序列化为 json,到目前为止,我设法让它适用于除数组以外的所有内容。
这是我的代码:
配置:
#FOSRestBundle
fos_rest:
param_fetcher_listener: true
body_listener:
enabled: true
decoders:
json: fos_rest.decoder.json
format_listener:
rules:
- { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }
body_converter:
enabled: true
#validate: true
view:
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
view_response_listener: 'force'
formats:
xml: false
json: true
templating_formats:
html: true
exception:
codes:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404
'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT
messages:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': true
allowed_methods_listener: true
access_denied_listener:
json: true
这是控制器
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use JMS\DiExtraBundle\Annotation\Inject;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\View;
use FOS\RestBundle\Controller\FOSRestController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
class DefaultController extends FOSRestController {
/**
* @Post("/rest", name="rest_test")
* @ParamConverter("myArr", converter="fos_rest.request_body")
* @View
* @param Request $request
*/
public function restAction(Request $request, array $myArr) {
return $myArr;
}
}
当我尝试从我的休息客户端调用它时(将 [1, 2]
作为请求正文)我收到此错误:
{
"code": 500,
"message": "Converter 'fos_rest.request_body' does not support conversion of parameter 'myArr'."
}
如果我将 myArr
变成一个对象(即我将其类型从 array
更改为 MyObject
,包含 number
变量 myVar
)并发送反映该对象结构的数据(例如 {"myVar": 2}
)它工作正常,但不适用于数组。
FOS Rest 主体转换器的目的是填充对象,而不是数组。你可以尝试实现你自己的参数转换器(see this documentation),但我真的不确定你能否实现你想要的。
无论如何,处理对象不是更干净吗?它可以让您确保收到的数据符合您的预期,使用验证等等...
经过几天的代码编写以及与 FoS 的一位合作者的愉快对话 https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1582 我发现,如果您使用的是 JMS 序列化程序包,则只需编写 array
在参数转换器的 class 字段中,它将反序列化为一个数组。我想我应该早点尝试
@ParamConverter("myarr", class="array", converter="fos_rest.request_body")
它甚至可以反序列化对象数组(只要它们相同 class,我猜)
@ParamConverter("myarr", class="array<Namespace/Class>", converter="fos_rest.request_body")
更新
我正在更新这个答案,因为我停止使用 JMS Serializer 并开始使用 Symfony Serializer,它对对象数组有不同的语法:
@ParamConverter("myarr", class="Namespace/Class[]", converter="fos_rest.request_body")
普通数组语法未受影响
我正在尝试使用 Symfony 3 和 FOSRestBundle 制作 Rest 网络服务。
我来自 Spring + Jackson 背景,所以我正在努力做到这一点,以便您可以将对象作为请求主体传递给控制器,请求主体成为函数参数,return 对象被序列化为 json,到目前为止,我设法让它适用于除数组以外的所有内容。
这是我的代码:
配置:
#FOSRestBundle
fos_rest:
param_fetcher_listener: true
body_listener:
enabled: true
decoders:
json: fos_rest.decoder.json
format_listener:
rules:
- { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }
body_converter:
enabled: true
#validate: true
view:
mime_types:
json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
view_response_listener: 'force'
formats:
xml: false
json: true
templating_formats:
html: true
exception:
codes:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404
'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT
messages:
'Symfony\Component\Routing\Exception\ResourceNotFoundException': true
allowed_methods_listener: true
access_denied_listener:
json: true
这是控制器
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use JMS\DiExtraBundle\Annotation\Inject;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\View;
use FOS\RestBundle\Controller\FOSRestController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
class DefaultController extends FOSRestController {
/**
* @Post("/rest", name="rest_test")
* @ParamConverter("myArr", converter="fos_rest.request_body")
* @View
* @param Request $request
*/
public function restAction(Request $request, array $myArr) {
return $myArr;
}
}
当我尝试从我的休息客户端调用它时(将 [1, 2]
作为请求正文)我收到此错误:
{
"code": 500,
"message": "Converter 'fos_rest.request_body' does not support conversion of parameter 'myArr'."
}
如果我将 myArr
变成一个对象(即我将其类型从 array
更改为 MyObject
,包含 number
变量 myVar
)并发送反映该对象结构的数据(例如 {"myVar": 2}
)它工作正常,但不适用于数组。
FOS Rest 主体转换器的目的是填充对象,而不是数组。你可以尝试实现你自己的参数转换器(see this documentation),但我真的不确定你能否实现你想要的。
无论如何,处理对象不是更干净吗?它可以让您确保收到的数据符合您的预期,使用验证等等...
经过几天的代码编写以及与 FoS 的一位合作者的愉快对话 https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1582 我发现,如果您使用的是 JMS 序列化程序包,则只需编写 array
在参数转换器的 class 字段中,它将反序列化为一个数组。我想我应该早点尝试
@ParamConverter("myarr", class="array", converter="fos_rest.request_body")
它甚至可以反序列化对象数组(只要它们相同 class,我猜)
@ParamConverter("myarr", class="array<Namespace/Class>", converter="fos_rest.request_body")
更新 我正在更新这个答案,因为我停止使用 JMS Serializer 并开始使用 Symfony Serializer,它对对象数组有不同的语法:
@ParamConverter("myarr", class="Namespace/Class[]", converter="fos_rest.request_body")
普通数组语法未受影响