【问题标题】:Symfony2 FOSRESTBundle serialization entity array to JSONSymfony2 FOSRESTBundle 序列化实体数组到 JSON
【发布时间】:2018-02-20 18:46:34
【问题描述】:

我在尝试用 JSON 序列化实体 Game 数组时遇到问题。 一开始我有一个循环引用异常,我设法修复了(但也许我的解决方案是问题的根源)。

目前我的请求 /games 返回一个有效的 JSON 数组,但未正确显示在浏览器中,并且应用程序无法解析它。 Chrome 向我返回以下错误:

资源被解释为 Document 但以 MIME 类型传输 应用程序/json

令人惊讶的是,我确实将 Content-Type 作为 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();
    }

App/Config/config.yml :

# 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);
}

这里是用于获取 /games 的标头:

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

还有那些获得/players的:

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

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

【问题讨论】:

    标签: json rest symfony serialization mime-types


    【解决方案1】:

    应用程序/json 内容类型不正确,因此我设法在计数器中手动修复 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-14
      • 2016-01-07
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多