2017-03-17 15 views
0

我想不出如何反序列化一個ID數組中的對象?這是一個簡單的例子,我的數組。如何反序列化jms中的數組ID?

"roles":["1","2","3"] 

但是,當試圖我得到的錯誤,對象預期的類AppBundle \ Entity \ Role ...是有這個東西呢?謝謝大家的關注!

回答

2

問題是LBA在他的回答中提到的問題。基本上爲了讓jms串行器創建一個對象,它需要提供一個數組。如果您可以改變api的結構,那麼解決方案也不錯。

我假設你的$角色JMS配置看起來像這樣

/** 
* @var ArrayCollection 
* 
* @JMS\Expose 
* @JMS\Accessor(setter="setRoles") 
* @JMS\SerializedName("roles") 
* @JMS\Type("ArrayCollection<Role>") 
* @JMS\Groups({"...."}) 
* 
*/ 
private $roles; 

在這種情況下將JMS期望獲得與就像LBA提到的數組的數組。如果你希望他保留當前結構(「角色」:[「1」,「2」,「3」])而不是「角色」:[「id」:1],[「id」:2], [「id」:3]],還有一個選擇。您可以擴展JsonDeserializationVisitor,這是一個非常強大的工具,可以在您的工具庫中使用jms執行幾乎任何您喜歡的任何操作。

要做到這一點首先改變你@Type像這樣(你會明白爲什麼後者)

* @JMS\Type("ArrayCollection<Role,Expand<id>>") 

現在使用參數覆蓋,延長JsonDeserializationVisitor,這樣

<parameter key="jms_serializer.json_deserialization_visitor.class">MyBundle\Services\JsonDeserializationVisitor.php</parameter> 

然後去並定義新的訪客就像這樣。

<?php 

    namespace MyBundle\Services\JmsSerializer; 

    use JMS\Serializer\Context; 
    use JMS\Serializer\JsonDeserializationVisitor as ParentJsonDeserializationVisitor; 
    use JMS\Serializer\Metadata\ClassMetadata; 
    use JMS\Serializer\Metadata\PropertyMetadata; 

    class JsonDeserializationVisitor extends ParentJsonDeserializationVisitor 
    { 
     /** 
     * @param PropertyMetadata $metadata 
     * @param mixed $data 
     * @param Context $context 
     */ 
     public function visitProperty(PropertyMetadata $metadata, $data, Context $context) 
     { 
      //This type is the information you put into the @Type annotation. 
      $type = $metadata->type; 

      $expand = null; 
      ....... 
    /*Here you can extract the Expand<id> part that you added to the @Type config. 
The Expand part will help you identify the fact that this property needs to be expanded and the id part will tell you how to expand id. 
Based on if you do find this you will probably set a variable like $expand = $key, where $key is the "id" part.*/ 
      ...... 
      if ($expand !== null) { 
       $expandedData = []; 
       foreach($data as $key->$value) 
       { 
        $expandedData[$key]=["$expand":$value]; 
       } 
       parent::visitProperty($metadata, $expandedData, $context); 
      } else { 
       parent::visitProperty($metadata, $data, $context); 
      } 

     } 

這是基本的東西。不管你喜歡什麼,都可以自由地重構代碼,這只是爲了快速驗證概念。另外展開就是我如何將它命名爲例子。你可以用你喜歡的任何名字來使用它。對不起,沒有提供代碼來從$類型中提取這個,但我現在不記得$ type的結構。此外,如果您執行類似Expand <'id'>的操作,結構將發生變化,請使用它並查看哪種最適合您。基本上用這種方法,你可以擴展和添加任何你想要的jms類型的功能。例如,您可以添加類似

@JMS\Type("string<translatable>") 

,然後擴展JsonSerializationVisitor:visitString到返回之前的數據在$調用$ translator->反式($數據),所以你可以序列化之前翻譯的字符串。

像這樣的事情

<?php 

namespace MyBundle\Service\JmsSerializer; 

use JMS\Serializer\Context; 
use JMS\Serializer\JsonSerializationVisitor as ParentJsonSerializationVisitor; 
use Symfony\Component\Translation\Translator; 

class JsonSerializationVisitor extends ParentJsonSerializationVisitor 
{ 
    /** 
    * @var Translator; 
    */ 
    private $translator; 

    const TRANSLATABLE = "translatable"; 

    /** 
    * @param string $data 
    * @param array $type 
    * @param Context $context 
    * @return string 
    */ 
    public function visitString($data, array $type, Context $context) 
    { 
     $translatable = $this->getParameters(self::TRANSLATABLE, $type['params']); 
     if ($translatable) { 
      $data = (string)$this->translator->trans($data); 
     } 
     return parent::visitString($data, $type, $context); 
    } 
    ..................... 

希望這有助於。如果您有任何問題,請告訴我。

Alexandru Cosoi

+0

感謝您的回答,我發現了JsonDeserializationVisitor,幫助我解決了我的問題。感謝您的全面解釋和說明例子! – Seintero

0

它反序列化您的陣列,但它會嘗試它反序列化爲AppBundle\Entity\Role類型的對象的數組,其似乎不與您的值"1""2"等,因此兼容拋出,因爲它不能instansiate對象的錯誤。

您必須確保您的內容適合預期的課程。

如果你可以共享你的類定義Role我們可以幫助你如何看待你的數組(例如[[「id」:1],[「id」:2],[「id 「:3]]可能)。

+0

感謝您的回覆。它適用於數組看起來像'[[「id」:1],[「id」:2],[「id」:3]]'但問題是我得到請求json數組, [id,id,id]' – Seintero

+0

然後你要麼改變你如何得到它(你顯然不能),要麼在反序列化之前轉換請求 - 因爲你必須更多地展示Controller的外觀。 – LBA