使用FOSRestBundle

时间:2016-09-29 19:16:49

标签: php rest symfony fosrestbundle jmsserializerbundle

我正在尝试使用Symfony 3和FOSRestBundle创建Rest Web服务 我来自Spring + Jackson背景,所以我试图让它成为可以将对象传递给控制器​​作为请求体,成为函数参数并返回被序列化为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})它工作正常,但它不适用于数组。

2 个答案:

答案 0 :(得分:5)

经过几天玩弄代码并与FoS的一位合作者https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1582进行了很好的对话后,我发现,如果您使用的是JMS Serializer Bundle(我认为每个人都有),你可以在param转换器的类字段中写入array,它会将其反序列化为一个数组。我应该早点尝试一下

@ParamConverter("myarr", class="array", converter="fos_rest.request_body")

它甚至可以反序列化对象数组(只要它们是同一个类,我猜)

@ParamConverter("myarr", class="array<Namespace/Class>", converter="fos_rest.request_body")

UPDATE 我更新了这个问题,因为我停止使用JMS Serializer并开始使用Symfony Serializer,它对于对象数组有不同的语法:

@ParamConverter("myarr", class="Namespace/Class[]", converter="fos_rest.request_body")

正常数组语法未受影响

答案 1 :(得分:1)

FOS Rest body转换器的目的是填充对象,而不是数组。你可以尝试实现自己的param转换器(see this documentation),但我真的不确定你能达到你想要的效果。

无论如何,处理物体会不会更干净?它可以让您确保您收到的数据符合您的预期,使用验证等等......