Làm cách nào để gửi phản hồi JSON trong bộ điều khiển symfony2


90

Tôi đang sử dụng jQueryđể chỉnh sửa biểu mẫu được tích hợp sẵn Symfony.

Tôi đang hiển thị biểu mẫu trong jQueryhộp thoại và sau đó gửi nó.

Dữ liệu được nhập chính xác vào cơ sở dữ liệu.

Nhưng tôi không biết liệu tôi có cần gửi JSONlại một số cho hay không jQuery. Thực sự tôi hơi bối rối với JSONđiều này.

Giả sử tôi đã thêm một hàng trong bảng của mình với `` jQuery và khi tôi gửi biểu mẫu thì sau khi dữ liệu được gửi, tôi muốn gửi lại những dữ liệu hàng đó để tôi có thể thêm động hàng trong bảng để hiển thị dữ liệu đã thêm.

Tôi bối rối làm thế nào có thể lấy lại dữ liệu đó.

Đây là mã hiện tại của tôi:

$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');               
}

Đây chỉ là mẫu với thông báo thành công.

Câu trả lời:


187

Symfony 2.1

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

return $response;

Symfony 2.2 trở lên

Bạn có lớp JsonResponse đặc biệt , lớp này tuần tự hóa mảng thành JSON:

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

Nhưng nếu vấn đề của bạn là Làm thế nào để tuần tự hóa thực thể thì bạn nên xem JMSSerializerBundle

Giả sử rằng bạn đã cài đặt nó, bạn chỉ cần làm

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

return new Response($serializedEntity);

Bạn cũng nên kiểm tra các sự cố tương tự trên StackOverflow:


1
Vậy làm cách nào để chúng ta Serialize entity AND gửi nó dưới dạng Phản hồi JSON? Tôi đã tìm kiếm điều đó trong một tuần .. stackoverflow.com/questions/14798532/…
George Katsanos

Bạn cũng có thể sử dụng symfony JsonResponse (Symfony \ Component \ HttpFoundation \ JsonResponse)
Kiddo

5
Tốt hơn là đặt tiêu đề kiểu nội dung trả về Phản hồi mới ($ serializedEntity, 200, array ('Content-Type' => 'application / json'));
Sergii Smirnov

Đề xuất của Sergii là tốt nhất (ít nhất là đối với tôi), nếu tôi không đặt Loại nội dung, trên máy khách, tôi sẽ nhận được một loại nội dung văn bản / html. Nếu tôi sử dụng JsonResponse, vì một số lý do kỳ lạ, tôi nhận được một chuỗi duy nhất có nội dung bên trong
LuisF

56

Symfony 2.1 có một lớp JsonResponse .

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

Mảng được truyền vào sẽ được mã hóa JSON, mã trạng thái sẽ mặc định là 200 và loại nội dung sẽ được đặt thành application / json.

Ngoài ra còn có một setCallbackchức năng tiện dụng cho JSONP.


16

Kể từ Symfony 3.1, bạn có thể sử dụng Trình trợ giúp JSON 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

Để hoàn thành câu trả lời @thecatontheflat, tôi cũng khuyên bạn nên bọc hành động của bạn bên trong một try … catchkhối. Điều này sẽ ngăn điểm cuối JSON của bạn không bị phá vỡ ngoại lệ. Đây là bộ xương tôi sử dụng:

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(),
        ]);

    }
}

Bằng cách này, điểm cuối của bạn sẽ hoạt động nhất quán ngay cả trong trường hợp có lỗi và bạn sẽ có thể xử lý chúng ngay từ phía khách hàng.


8

Nếu dữ liệu của bạn đã được tuần tự hóa:

a) gửi phản hồi 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) gửi phản hồi JSONP (có gọi lại)

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

Nếu dữ liệu của bạn cần được tuần tự hóa:

c) gửi phản hồi JSON

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

d) gửi phản hồi JSONP (có gọi lại)

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

e) sử dụng các nhóm trong Symfony 3.xx

Tạo nhóm bên trong Thực thể của bạn

<?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;
    }

    // ...
}

Bình thường hóa Đối tượng Doctrine của bạn bên trong logic của ứng dụng của bạn

<?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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.