【问题标题】:Symfony: How to return a JSON response from a Before Filter (Listener)?Symfony:如何从前置过滤器(监听器)返回 JSON 响应?
【发布时间】:2016-08-25 21:56:39
【问题描述】:

通过关注this example,我设法设置了以下监听器/前置过滤器,以在处理任何控制器操作之前解析对我的 API 端点(即 /api/v1)的所有请求。这用于验证请求类型并在不满足某些条件时抛出错误。

我想根据应用程序环境状态来区分错误响应。如果我们在开发或测试中,我只是想抛出遇到的错误。或者,如果在生产模式下,我想将错误作为 JSON 响应返回。这可能吗?如果没有,我怎么能做类似的事情?

我正在使用 Symfony v3.1.*,如果这有什么不同的话。

namespace AppBundle\EventListener;

use AppBundle\Interfaces\ApiAuthenticatedController;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class ApiBeforeListener
{
    /**
     * @var \Symfony\Component\DependencyInjection\ContainerInterface
     */
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * Validates a request for API resources before serving content
     *
     * @param \Symfony\Component\HttpKernel\Event\FilterControllerEvent $event
     * @return mixed
     */
    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();

        if (!is_array($controller))
            return;

        if ($controller[0] instanceof ApiAuthenticatedController) {

            $headers = $event->getRequest()->headers->all();

            // only accept ajax requests
            if(!isset($headers['x-requested-with'][0]) || strtolower($headers['x-requested-with'][0]) != 'xmlhttprequest') {

                $error = new AccessDeniedHttpException('Unsupported request type.');

                if (in_array($this->container->getParameter("kernel.environment"), ['dev', 'test'], true)) {
                    throw $error;
                } else {
                    // return json response here for production environment
                    // 
                    // For example:
                    // 
                    // header('Content-Type: application/json');
                    // 
                    // return json_encode([
                    //  'code'    => $error->getCode(),
                    //  'status'  => 'error',
                    //  'message' => $error->getMessage()
                    // ]);
                }
            }
        }
    }

}

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    与大多数事件不同,FilterControllerEvent 不允许您返回响应对象。如果它确实很好,但很好。

    您有两个基本选择。

    最好的方法是简单地抛出一个异常,然后添加一个异常监听器。然后异常监听器可以根据环境返回一个 JsonResponse。

    另一种可能是创建一个只返回 JsonResponse 然后使用 $event->setController($jsonErrorController) 指向它的控制器。

    但我认为抛出异常可能是你最好的选择。

    更多详情:http://symfony.com/doc/current/reference/events.html

    【讨论】:

    • @Cared 您的第一个建议听起来不错。我会试一试并报告。
    • @DeepakSingh 我没有。不得不做一些不同的方法。不过现在想不起来了。
    • @NickLaw 我遇到了与您相同的情况。如果可以,请放弃一些有关如何解决此问题的建议。
    • @DeepakSingh 鉴于这个问题已经有将近两年的历史了,您可能会考虑自己提出问题。请说明此答案中的两个建议对您不起作用的原因。
    猜你喜欢
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2021-04-16
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    相关资源
    最近更新 更多