代码之家  ›  专栏  ›  技术社区  ›  Doshibu

Symfony2 FOSRESTBundle序列化实体数组到JSON

  •  0
  • Doshibu  · 技术社区  · 7 年前

    我在尝试序列化实体数组时遇到问题 游戏 在JSON中。

    被解释为文档但使用MIME类型传输的资源 应用程序/json

    令人惊讶的是,我确实将内容类型发送为application/json。 完全相同的标题用于另一个请求/播放器,并正确显示和解析,没有错误。

    <?php
    
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * Game
     *
     * @ORM\Table(name="game")
     * @ORM\Entity(repositoryClass="AppBundle\Repository\GameRepository")
     */
    class Game
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @ORM\ManyToOne(targetEntity="AppBundle\Entity\TournamentType", inversedBy="games")
         */
        private $refType;
    
        /**
         * @var \DateTime
         *
         * @ORM\Column(name="TournamentDate", type="date")
         */
        private $tournamentDate;
    
        /**
         * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Ground", inversedBy="games")
         */
        private $ground;
    
        /**
         * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Referee", inversedBy="games")
         */
        private $referee;
    
        /**
        * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Player", cascade={"persist"})
        */
        private $players;
    
        /**
         * @var int
         *
         * @ORM\Column(name="NbSetsPlayerOne", type="integer")
         */
        private $nbSetsPlayerOne;
    
        /**
         * @var int
         *
         * @ORM\Column(name="NbSetsPlayerTwo", type="integer")
         */
        private $nbSetsPlayerTwo;
    
        /**
        * @var boolean
        * 
        * @ORM\Column(name="IsOver", type="boolean")
        */
        private $isOver;
    
        public function __construct(){
            $this->players = new \Doctrine\Common\Collections\ArrayCollection();
        }
    

    实体玩家:

    <?php
    
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * Player
     *
     * @ORM\Table(name="player")
     * @ORM\Entity(repositoryClass="AppBundle\Repository\PlayerRepository")
     */
    class Player
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\Column(name="LastName", type="string", length=255)
         */
        private $lastName;
    
        /**
         * @var string
         *
         * @ORM\Column(name="FirstName", type="string", length=255)
         */
        private $firstName;
    
        /**
         * @var string
         *
         * @ORM\Column(name="Sexe", type="string", length=255)
         */
        private $sexe;
    
        /**
         * @var string
         *
         * @ORM\Column(name="Country", type="string", length=255)
         */
        private $country;
    
        /**
         * @var int
         *
         * @ORM\Column(name="Ranking", type="integer")
         */
        private $ranking;
    
        /**
        * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Game", cascade={"persist"})
        */
         private $games;
    
    
        public function __construct(){
            $this->games = new \Doctrine\Common\Collections\ArrayCollection();
        }
    

    # FOSRestBundle API Configuration
    fos_rest:
        format_listener:
            rules:
                - { path: '^/game', priorities: 'json', fallback_format: json, prefer_extension: true }
                - { path: '^/ground', priorities: 'json', fallback_format: json, prefer_extension: true }
                - { path: '^/player', priorities: 'json', fallback_format: json, prefer_extension: true }
                - { path: '^/referee', priorities: 'json', fallback_format: json, prefer_extension: true }
                - { path: '^/tournament-type', priorities: 'json', fallback_format: json, prefer_extension: true }
                - { path: '^/user', priorities: 'json', fallback_format: json, prefer_extension: true }
                - { path: '^/', priorities: 'json', fallback_format: json, prefer_extension: true }
    

    游戏控制器:

    /**
     * getGamesAction
     *
     * @Get("/games")
     * 
     * @param Request $request
     * @return type
     */
    public function getGamesAction(Request $request) {        
        $games = $this->getDoctrine()->getManager()->getRepository("AppBundle:Game")->findAll();     
        if (count($games) === 0) {
            $view = $this->view("No Game found.", 404);
            return $this->handleView();
        }
    
        $encoder = new JsonEncoder();
        $normalizer = new ObjectNormalizer();
        $normalizer->setIgnoredAttributes(array('games', 'players'));
        $normalizer->setCircularReferenceHandler(function ($object) {
            return $object->getId();
        });
        $serializer = new Serializer(array($normalizer), array($encoder));
        $data = $serializer->serialize($games, 'json');
        $view = $this->view($data)
                     ->setTemplateVar('games')
                     ->setTemplate($this->template);
        //             ->setHeader('Content-Type', 'application/json; charset=UTF-8');
        return $this->handleView($view);
    }
    

    以下是用于获取 :

    Cache-Control: no-cache
    Connection: close
    Content-Type: application/json
    Date: Tue, 12 Sep 2017 12:35:45 +0200, Tue, 12 Sep 2017 10:35:45 GMT
    Host: localhost:8000
    X-Debug-Token: d072dd
    X-Debug-Token-Link: http://localhost:8000/app_dev.php/_profiler/d072dd
    X-Powered-By: PHP/7.1.1
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding: gzip, deflate
    Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
    Cache-Control: max-age=0
    Connection: keep-alive
    Cookie: cookieconsent_dismissed=yes; _ga=GA1.1.372052120.1482146348; PHPSESSID=l1fgb45492lr02a6hi10rat7ha
    Host: localhost:8000
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
    

    /球员

    Cache-Control: no-cache
    Connection: close
    Content-Type: application/json
    Date: Tue, 12 Sep 2017 12:38:18 +0200, Tue, 12 Sep 2017 10:38:18 GMT
    Host: localhost:8000
    X-Debug-Token: 609af7
    X-Debug-Token-Link: http://localhost:8000/app_dev.php/_profiler/609af7
    X-Powered-By: PHP/7.1.1
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding: gzip, deflate
    Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
    Connection: keep-alive
    Cookie: cookieconsent_dismissed=yes; _ga=GA1.1.372052120.1482146348; PHPSESSID=l1fgb45492lr02a6hi10rat7ha
    Host: localhost:8000
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
    

    您可以访问以下示例: 呈现的json视图: JSON shared URL

    1 回复  |  直到 7 年前
        1
  •  0
  •   Doshibu    7 年前

    应用程序/json内容类型不正确,因此我设法在countroller中手动修复UTF-8编码(这是应用程序/json的默认编码)和返回给json对象的字符串。

    编码:

    $encoder = new JsonEncoder(new JsonEncode(JSON_UNESCAPED_UNICODE), new JsonDecode(false));
    

    转换JSON对象中的字符串:

    $this->view(json_decode($data, true))
    

    /**
     * getGamesAction
     *
     * @Get("/games")
     * 
     * @param Request $request
     * @return type
     */
    public function getGamesAction(Request $request) {        
        $games = $this->getDoctrine()->getManager()->getRepository("AppBundle:Game")->findAll();     
        if (count($games) === 0) {
            $view = $this->view("No Game found.", 404);
            return $this->handleView();
        }
    
        $encoder = new JsonEncoder(new JsonEncode(JSON_UNESCAPED_UNICODE), new JsonDecode(false));
        $normalizer = new ObjectNormalizer();
        $normalizer->setIgnoredAttributes(array('games', 'players'));
        $normalizer->setCircularReferenceHandler(function ($object) {
            return $object->getId();
        });
        $serializer = new Serializer(array($normalizer), array($encoder));
        $data = $serializer->serialize($games, 'json');
        $view = $this->view(json_decode($data, true))
                     ->setTemplateVar('games')
                     ->setTemplate($this->template)
                     ->setHeader('Content-Type', 'application/json; charset=UTF-8')
                     ->setFormat('json');
        return $this->handleView($view);
    }