简体   繁体   English

使用FOSRestBundle将POST请求主体序列化为数组

[英]Serialize POST request body into array with FOSRestBundle

I am trying to make a Rest web service using Symfony 3 and FOSRestBundle. 我正在尝试使用Symfony 3和FOSRestBundle创建Rest Web服务。
I come from a Spring + Jackson background so i'm trying to make it so that you can pass objects to controllers as request body that become function parameters and return objects that get serialized into json, so far i managed to make it work for everything except for arrays. 我来自Spring + Jackson背景,所以我试图让它成为可以将对象传递给控制器​​作为请求体,成为函数参数并返回被序列化为json的对象,到目前为止我设法让它适用于所有事情除了数组。
This is my code: 这是我的代码:

configuration: 组态:

#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

This is the controller 这是控制器

<?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;
    }
}

When i try to call this from my rest client (putting [1, 2] as request body) i receive this error: 当我尝试从我的休息客户端调用此项(将[1, 2]作为请求主体)时,我收到此错误:

{
  "code": 500,
  "message": "Converter 'fos_rest.request_body' does not support conversion of parameter 'myArr'."
}

If i turn myArr into an object (that is i change its type from array to MyObject , containing the number variable myVar ) and send data that reflects that object structure (such as {"myVar": 2} ) it works fine, but it doesn't work with an array. 如果我将myArr转换为一个对象(即我将其类型从array更改为MyObject ,包含number变量myVar )并发送反映该对象结构的数据(例如{"myVar": 2} ),它可以正常工作,但它不适用于数组。

After days of toying with the code and this nice conversation with one of the collaborators of FoS https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1582 i have discovered that, if you are using the JMS Serializer Bundle (Which I think everyone has), you can just write array in the class field of the param converter and it will deserialize it into an array. 经过几天玩弄代码和与FoS的一个合作者的良好对话https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1582我发现,如果你使用的是JMS Serializer Bundle(我认为每个人都有),您可以在param转换器的类字段中编写array ,并将其反序列化为数组。 I should've tried it earlier i guess 我猜我应该早点尝试过

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

It can even deserialize arrays of objects (as long as they are the same class, i guess) 它甚至可以反序列化对象数组(只要它们是同一个类,我猜)

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

UPDATE I'm updating this question since i stopped using JMS Serializer and started using the Symfony Serializer, which has a different syntax for arrays of objects: 更新我正在更新这个问题,因为我停止使用JMS Serializer并开始使用Symfony Serializer,它具有不同的对象数组语法:

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

Normal arrays syntax is untouched 正常数组语法不受影响

The FOS Rest body convertor purpose is to populate objects, not arrays. FOS Rest体转换器的目的是填充对象,而不是数组。 You can try to implement your own param converter ( see this documentation ), but I'm really not sure you can achieve what you want. 你可以尝试实现自己的param转换器( 参见本文档 ),但我真的不确定你能达到你想要的效果。

Anyway, dealing with objects wouldn't be cleaner? 无论如何,处理物体会不会更干净? It would allow you to be sure that the data you're receiving match what you expect, to use validations, and so on... 它可以让您确保您收到的数据符合您的预期,使用验证等等......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM