2013-02-10 51 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; 
}