0

我有一个通过 SensioGeneratorBundle 生成的 CRUD 表单,如此处所述。这很好用。

但是,如果“Accept”HTTP 标头仅包含“application/json”,我还想返回 JSON,而不是 HTML 响应。我正在开发 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 而不呈现通常视图的“正确”方式是什么。

谢谢!

4

1 回答 1

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 中可读的结构。

于 2013-05-23T00:07:24.190 回答