Come posso inviare una risposta JSON nel controller symfony2


90

Sto usando jQueryper modificare il mio modulo che è integrato Symfony.

Sto mostrando il modulo nella jQueryfinestra di dialogo e poi lo invio.

I dati vengono inseriti correttamente nel database.

Ma non so se devo rispedirne qualcuno JSONa jQuery. In realtà sono un po 'confuso con la JSONcosa.

Supponiamo di aver aggiunto una riga nella mia tabella con `` jQuery e quando invio il modulo, dopo che i dati sono stati inviati, voglio restituire quei dati di riga in modo da poter aggiungere dinamicamente la riga della tabella per mostrare i dati aggiunti.

Sono confuso su come recuperare quei dati.

Questo è il mio codice attuale:

$editForm = $this->createForm(new StepsType(), $entity);

$request = $this->getRequest();

$editForm->bindRequest($request);

if ($editForm->isValid()) {
    $em->persist($entity);
    $em->flush();

    return $this->render('::success.html.twig');               
}

Questo è solo il modello con il messaggio di successo.

Risposte:


187

Symfony 2.1

$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');

return $response;

Symfony 2.2 e versioni successive

Hai una classe JsonResponse speciale , che serializza l'array in JSON:

return new JsonResponse(array('name' => $name));

Ma se il tuo problema è come serializzare l'entità , dovresti dare un'occhiata a JMSSerializerBundle

Supponendo che tu lo abbia installato, dovrai semplicemente farlo

$serializedEntity = $this->container->get('serializer')->serialize($entity, 'json');

return new Response($serializedEntity);

Dovresti anche verificare la presenza di problemi simili su StackOverflow:


1
Quindi, come serializziamo l'entità e la inviamo come risposta JSON? Ho cercato per questo per una settimana .. stackoverflow.com/questions/14798532/...
George Katsanos

Puoi anche usare symfony JsonResponse (Symfony \ Component \ HttpFoundation \ JsonResponse)
Kiddo

5
È meglio impostare l'intestazione del tipo di contenuto restituisce una nuova risposta ($ serializedEntity, 200, array ('Content-Type' => 'application / json'));
Sergii Smirnov

Il suggerimento di Sergii è il migliore (almeno per me), se non imposto il Content-Type, sul client riceverò un content-type text / html. Se uso JsonResponse, per qualche strano motivo ottengo una singola stringa con il contenuto all'interno
LuisF

56

Symfony 2.1 ha una classe JsonResponse .

return new JsonResponse(array('name' => $name));

L'array passato sarà codificato in JSON, il codice di stato sarà predefinito su 200 e il tipo di contenuto sarà impostato su application / json.

C'è anche una comoda setCallbackfunzione per JSONP.


16

Da Symfony 3.1 puoi usare JSON Helper http://symfony.com/doc/current/book/controller.html#json-helper

public function indexAction()
{
// returns '{"username":"jane.doe"}' and sets the proper Content-Type header
return $this->json(array('username' => 'jane.doe'));

// the shortcut defines three optional arguments
// return $this->json($data, $status = 200, $headers = array(), $context = array());
}

10

Per completare la risposta @thecatontheflat, consiglierei di racchiudere anche la tua azione all'interno di un try … catchblocco. Ciò impedirà al tuo endpoint JSON di non funzionare in caso di eccezioni. Ecco lo scheletro che uso:

public function someAction()
{
    try {

        // Your logic here...

        return new JsonResponse([
            'success' => true,
            'data'    => [] // Your data here
        ]);

    } catch (\Exception $exception) {

        return new JsonResponse([
            'success' => false,
            'code'    => $exception->getCode(),
            'message' => $exception->getMessage(),
        ]);

    }
}

In questo modo il tuo endpoint si comporterà in modo coerente anche in caso di errori e sarai in grado di trattarli direttamente dal lato client.


8

Se i tuoi dati sono già serializzati:

a) invia una risposta JSON

public function someAction()
{
    $response = new Response();
    $response->setContent(file_get_contents('path/to/file'));
    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

b) invia una risposta JSONP (con callback)

public function someAction()
{
    $response = new Response();
    $response->setContent('/**/FUNCTION_CALLBACK_NAME(' . file_get_contents('path/to/file') . ');');
    $response->headers->set('Content-Type', 'text/javascript');
    return $response;
}

Se i tuoi dati devono essere serializzati:

c) invia una risposta JSON

public function someAction()
{
    $response = new JsonResponse();
    $response->setData([some array]);
    return $response;
}

d) invia una risposta JSONP (con callback)

public function someAction()
{
    $response = new JsonResponse();
    $response->setData([some array]);
    $response->setCallback('FUNCTION_CALLBACK_NAME');
    return $response;
}

e) utilizzare i gruppi in Symfony 3.xx

Crea gruppi all'interno delle tue Entità

<?php

namespace Mindlahus;

use Symfony\Component\Serializer\Annotation\Groups;

/**
 * Some Super Class Name
 *
 * @ORM    able("table_name")
 * @ORM\Entity(repositoryClass="SomeSuperClassNameRepository")
 * @UniqueEntity(
 *  fields={"foo", "boo"},
 *  ignoreNull=false
 * )
 */
class SomeSuperClassName
{
    /**
     * @Groups({"group1", "group2"})
     */
    public $foo;
    /**
     * @Groups({"group1"})
     */
    public $date;

    /**
     * @Groups({"group3"})
     */
    public function getBar() // is* methods are also supported
    {
        return $this->bar;
    }

    // ...
}

Normalizza il tuo oggetto Doctrine all'interno della logica della tua applicazione

<?php

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
// For annotations
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;

...

$repository = $this->getDoctrine()->getRepository('Mindlahus:SomeSuperClassName');
$SomeSuperObject = $repository->findOneById($id);

$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer($classMetadataFactory);
$callback = function ($dateTime) {
    return $dateTime instanceof \DateTime
        ? $dateTime->format('m-d-Y')
        : '';
};
$normalizer->setCallbacks(array('date' => $callback));
$serializer = new Serializer(array($normalizer), array($encoder));
$data = $serializer->normalize($SomeSuperObject, null, array('groups' => array('group1')));

$response = new Response();
$response->setContent($serializer->serialize($data, 'json'));
$response->headers->set('Content-Type', 'application/json');
return $response;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.