2013-02-10 53 views
3

这里是我的控制器的方法:Symfony2的JSON响应返回奇怪的UTF字符

public function sendjsonAction() 
    { 

    $message = $this->getDoctrine() 
    ->getRepository('AcmeStoreBundle:Message') 
    ->findAll(); 
    $serializer = new Serializer(array(new GetSetMethodNormalizer()), array('message' => new 
JsonEncoder())); 
    $message = $serializer->serialize($message, 'json');  
    return new JsonResponse($message); 

    } 

这里是我的路由器:

acme_store_sendjson: 
    pattern: /sendjson/ 
    defaults: { _controller: AcmeStoreBundle:Default:sendjson} 

这里就是我得到的,当我去/ sendjson /:

"[{\u0022id\u0022:1,\u0022iam\u0022:1,\u0022youare\u0022:2,\u0022lat\u0022:50.8275853,\u0022lng\u0022:4.3809764,\u0022date\u0022:{\u0022lastErrors\u0022:{\u0022warning_count\u0022:0,\u0022warnings\u0022:[],\u0022error_count\u0022:0,\u0022errors\u0022:[]},\u0022timezone\u0022:{\u0022name\u0022:\u0022UTC\u0022,\u0022location\u0022:{\u0022country_code\u0022:\u0022??

(与此类似)

我试图做一个Ajax调用(使用jQuery)有以下几点:

$.getJSON('/app_dev.php/sendjson', function(data) { 
    var items = []; 

    $.each(data, function(key, val) { 
    items.push('<li id="' + key + '">' + val + '</li>'); 
    }); 

    $('<ul/>', { 
    'class': 'my-new-list', 
    html: items.join('') 
    }).appendTo('body'); 
}); 

我也得到一个

Uncaught TypeError: Cannot use 'in' operator to search for '1549' in [{"id":1,... 

当我改变的Symfony2的响应类型,我得到的名单

[对象] [对象] [对象] [对象] [对象] [对象] ...

我做错了什么?我应该解析答案转换\ u0022到“或者是我从一开始就响应故障

编辑

我还可以通过改变控制器的尝试:?

public function sendjsonAction() 
    { 
$encoders = array(new XmlEncoder(), new JsonEncoder()); 
$normalizers = array(new GetSetMethodNormalizer()); 
$serializer = new Serializer($normalizers, $encoders); 

    $message = $this->getDoctrine() 
    ->getRepository('AcmeStoreBundle:Message') 
    ->findAll(); 
$serializer = $serializer->serialize($message, 'json'); 
    return new Response($serializer); 
} 

这一次我得到了有效的JSON,(根据Jsonlint)buuttt头不是应用程序/ JSON ...(有道理,因为我发送一个响应而不是JsonResponse ...)(但多数民众赞成我试图避免,因为JsonResponse似乎要改变添加奇怪的字符)

[{"id":1,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":2,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":3,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":4,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":5,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"},{"id":6,"iam":1,"youare":2,"lat":50.8275853,"lng":4.3809764,"msgbody":"I saw you over there what's up!"}] 
+0

你的PHP似乎罚款,\ u0022是一个引号。请调试你的JavaScript,错误应该在你的js代码中的某处。 – 2013-02-10 14:56:15

+0

js是正确的,直接从jquery.com,它工作时,我手动内联数据在数组中,并发送他们作为回应,所以问题是JSON ...我不应该有引号为\ u0022字符..(没有js那里 - 那是Symfony的页面) – 2013-02-10 15:01:22

+0

尝试新的响应($ message)。你得到了什么? – 2013-02-10 15:11:20

回答

4

我找到了答案。

1)只要JSON是有效的,它不“真的很重要”内容类型不是application/json而是text/html。我的JS不玩的原因是我要求val而不是val.msgbody之类的val属性。 :

所以我的JavaScript应

$.getJSON('/app_dev.php/sendjson', function(data) { 
    var items = []; 

    $.each(data, function(key, val) { 
    items.push('<li id="' + key + '">' + val.msgbody + '</li>'); 
    }); 

    $('<ul/>', { 
    'class': 'my-new-list', 
    html: items.join('') 
    }).appendTo('body'); 
}); 

如果在Content-Type是一个要求,那么控制器可以是这样的:

public function sendjsonAction() 
    { 
    $encoders = array(new JsonEncoder()); 
    $normalizers = array(new GetSetMethodNormalizer()); 
    $serializer = new Serializer($normalizers, $encoders); 
    $message = $this->getDoctrine() 
     ->getRepository('AcmeStoreBundle:Message') 
     ->findAll(); 
    $response = new Response($serializer->serialize($message, 'json')); 
    $response->headers->set('Content-Type', 'application/json'); 
    return $response; 
    } 
-2

的问题是要传递一个字符串JsonResponse而不是一个数组。

控制器代码是:

... 
return new JsonResponse($message) 
... 

控制器代码必须是:

... 
return new JsonResponse(json_decode($message, true)) 
... 
+0

不应该让他们解码然后重新编码一些东西。这会很好地减缓它。 – Seer 2014-09-10 13:49:06

2

序列化是正火的过程 - 使表示对象的阵列 - 和编码该表示(即到JSON或XML)。 JsonResponse负责编码部分(查看类的名称),因此您无法传递'序列化对象',否则它将被再次编码。 因此,解决方案仅归对象并将它传递给JsonResponse:

public function indexAction($id) 
{ 
    $repository = $this->getDoctrine()->getRepository('MyBundle:Product'); 
    $product = $repository->find($id); 

    $normalizer = new GetSetMethodNormalizer(); 

    $jsonResponse = new JsonResponse($normalizer->normalize($product)); 
    return $jsonResponse; 
}