2013-05-22 4 views
0

У меня есть CRUD-форма, сгенерированная через SensioGeneratorBundle, как described here. Это отлично работает.Возврат JSON на основе «Accept: application/json» с контроллера Symfony2

Однако, я хотел бы также вернуть JSON, а не ответы HTML, если заголовок HTTP «Accept» содержит только «application/json». Я работаю над прототипом службы JSON, и это поможет мне начать все начинать.

я понял, что я могу превратить свои объекты в строку JSON, как это:

use Symfony\Component\Serializer\Serializer; 
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer; 
use Symfony\Component\Serializer\Encoder\JsonEncoder; 

$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new 
JsonEncoder())); 
$json = $serializer->serialize($entity, 'json'); 

Однако, в конце, что $ содержит JSON строку, мои данные в формате JSON. Я хочу просто напрямую вывести это запрос, а не отображать обычное представление. Я попытался вернуть новый JsonResponse ($ json), но он перекодирует строку JSON, так что он заканчивается двойным кодированием.

Поэтому у меня есть два вопроса:

  1. Что такое «правильный» способ проверки заголовков HTTP запроса на? Я знаю, что могу просто посмотреть в $ _SERVER, но я думаю, что в Symfony2 может быть лучший способ сделать это.
  2. Что такое «правильный» способ вернуть строку JSON или перевести мои объекты в JSON, который возвращается прямо к запрашивающему, не отображая обычный вид.

Спасибо!

ответ

0

Это будет проверить, если текущий запрос XHR, а затем отправить обратно правильно отформатированные данные в формате JSON:

public function someAction(Request $request) 
{ 
    if ($request->isXmlHttpRequest()) { 
     $serializer = new Serializer(array(
      new GetSetMethodNormalizer() 
     ), array(
      'json' => new JsonEncoder() 
     )); 

     $response = $serializer->serialize(array(
      'success' => true, 
      'data' => array(
       'entity' => $entities, 
      ) 
     ), 'json'); 

     return new Response($response, 200, array('Content-Type' => 'application/json')); 
    } else { 
     // Run "normal" request code, render a view 
    } 
} 

Кстати, JMSSerializerBundle делает синтаксис сериализация более простым (потому что, давайте посмотрим правде в глаза, родной Symfony путь для этого уродливый), а также предоставляет некоторые дополнительные функции, такие как исключение полей объектов для сериализации (через аннотации).

С JMS, мой код выглядит следующим образом:

if ($request->isXmlHttpRequest()) { 
    $response = array('success' => true, 'data' => array(
     'entity' => $this->container->get('serializer')->serialize($entity, 'json'), 
     'lastPage' => $lastPage, 
    )); 
    return new Response(json_encode($response), 200, array('Content-Type' => 'application/json')); 
} 

И, наконец, «успех» и «данные» никоим образом не требуется, это просто структура я использую, чтобы разделить статус и данные должны быть видимы в JavaScript.

+0

Это замечательно! Мне пришлось немного изменить его, потому что объекты все еще были дважды закодированы. Вот что я придумал: '$ serializer = new Сериализатор (массив (новый GetSetMethodNormalizer()), массив ('json' => новый JsonEncoder());' '$ response = $ serializer-> serialize (array ('success' => true, 'data' => array ('entity' => $ entities,)), 'json'); ' ' $ result = new Response ($ response, 200, array ('Content -Type '=>' application/json ')); ' – Josh

+0

Итак, я не могу понять, как получить разрыв строки в комментариях. Вам нужно будет переформатировать код в моем предыдущем комментарии ... извините. Кроме того, мне пришлось изменить $ request на $ this-> getRequest(). – Josh

+0

К сожалению, я взял этот фрагмент из своего кода, и я делаю кодировку несколько иначе, чем вы. Прокомментируйте только теги кода поддержки, ничего больше;) Я буду запрашивать запросы, я отредактирую ответ –