从 Symfony2 控制器返回基于“Accept: application/json”的 JSON,而不修改每个控制器动作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16704111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Return JSON based on “Accept: application/json” from a Symfony2 controller without modifying each controller action
提问by Josh
I'm working on an app that I want to offer both JSON and HTML responses. Here's an example action method:
我正在开发一个应用程序,我想同时提供 JSON 和 HTML 响应。这是一个示例操作方法:
/**
* Lists all Boards entities.
*
* @Route("/", name="boards")
* @Method("GET")
* @Template()
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ScrumBoardServiceBundle:Boards')->findAll();
$acceptHeader = strtolower($this->getRequest()->headers->get('Accept'));
if ($acceptHeader === 'application/json') {
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new
JsonEncoder()));
$response = $serializer->serialize(array('success' => true, 'data' => array(
'entity' => $entities,
)), 'json');
$result = new Response($response, 200, array('Content-Type' => 'application/json'));
} else {
$result = array(
'entities' => $entities,
);
}
return $result;
}
This works fine. If you send in an HTTP Accept header that is exactlyapplication/json, you will get JSON back. Otherwise, you get the usual hTML view.
这工作正常。如果您发送的 HTTP Accept 标头恰好是application/json,您将得到 JSON。否则,您将获得通常的 hTML 视图。
This works fine, but I've got dozens of actions. I'd rather not repeat myself. I'm working on refactoring this code into something a little more generic... but I'm also wondering if this problem has already been solved by an existing Symfony2 bundle. Maybe something with annotations? Or a config setting? I haven't been able to find anything so far. But I am so new to Symfony I could very easily be missing something.
这工作正常,但我有几十个动作。我宁愿不重复自己。我正在努力将这段代码重构为更通用的东西……但我也想知道这个问题是否已经被现有的 Symfony2 包解决了。也许有注释的东西?还是配置设置?到目前为止,我还没有找到任何东西。但是我对 Symfony 太陌生了,我很容易遗漏一些东西。
回答by Denis V
As a generic idea, in case you want to avoid using 3rd party bundles, you may subscribe to the kernel.response event and play with the Response there, just in one common place.
作为一个通用的想法,如果您想避免使用 3rd 方包,您可以订阅 kernel.response 事件并在那里使用 Response,就在一个常见的地方。
Something like:
就像是:
//services.yml
//services.yml
services:
my.kernel.listener:
class: Acme\Bundle\AppBundle\EventListener\MyKernelListener
tags:
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
// MyKernelListener.php
// MyKernelListener.php
class MyKernelListener
{
public function onKernelResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();
$request = $event->getRequest();
// ... your logic ...
}
}
回答by Nicolai Fr?hlich
The bundle you are looking for is the FOSRestBundle.
您正在寻找的捆绑包是FOSRestBundle。
You can have it serve JSON based on Accept header or adding _format to your routes ... highly configurable.
您可以让它基于 Accept 标头提供 JSON 或将 _format 添加到您的路由...高度可配置。
Works nice with JMSSerializerBundle.
与JMSSerializerBundle配合使用很好。

