触发错误404.json.twig

Cra*_*aig 5 rest json symfony

我正在尝试让我的自定义json错误模板由Symfony返回,但它不断返回HTML版本.使用rest客户端我已将AcceptContent-Type设置为"application/json",但只返回error404.html.twig的内容,而不是error404.json.twig文件.

目前我正在通过一个完全无效的URL(即没有路由)对此进行测试,但是一旦我开始工作,我也会将其用于有效的URL,这些URL不会导致资源,并且内部代码会抛出HttpNotFoundException

Jas*_*man 4

在请求中设置标头实际上不会对返回的错误模板产生任何影响,尽管看起来这可能是逻辑路径。生成的错误模板基于请求格式,该格式可以在参数中设置_format,也可以在对象本身上手动设置Request这篇文章中有一个解决方案,但如果您收到 404 错误,则无法准确设置参数_format$request->setRequestFormat('json')从不存在路由的控制器进行调用。

Symfony 有非常好的文档说明如何自定义错误页面,包括您可能想要采用的路径,该路径会覆盖默认值ExceptionController。本质上,您将重写showAction()orfindTemplate()方法,该方法将采用Acceptheader 并检查application/json. 您还可以检查Content-Type标头作为附加要求。所以这是你的听众的声明:

# app/config/services.yml
services:
    app.exception_controller:
    class: AppBundle\Controller\CustomExceptionController
    arguments: ['@twig', '%kernel.debug%']
Run Code Online (Sandbox Code Playgroud)

然后设置Twig参数:

# app/config/config.yml
twig:
    exception_controller:  app.exception_controller:showAction
Run Code Online (Sandbox Code Playgroud)

现在定义您的类并覆盖您需要的相关部分。第一个示例showAction()通过检查Accept标头然后修改Request格式来覆盖:

namespace AppBundle\Controller;

use Symfony\Bundle\TwigBundle\Controller\ExceptionController;

class CustomExceptionController extends ExceptionController
{
    /*
     * {@inheritDoc}
     */
    public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null)
    {
        if (in_array('application/json', $request->getAcceptableContentTypes())) {
            $request->setRequestFormat('json');
        }

        parent::showAction($request, $exception, $logger);
    }
}
Run Code Online (Sandbox Code Playgroud)

Symfony 表示该findTemplate()方法是定位要使用的模板的方法,因此您可以将代码放在那里。下面是一个覆盖该函数的示例,Content-Type如果您需要满足这两个条件,则需要对标头进行额外检查:

namespace AppBundle\Controller;

use Symfony\Bundle\TwigBundle\Controller\ExceptionController;

class CustomExceptionController extends ExceptionController
{
    /*
     * {@inheritDoc}
     */
    protected function findTemplate(Request $request, $format, $code, $showException)
    {
        if (in_array('application/json', $request->getAcceptableContentTypes()) &&
            0 === strpos($request->headers->get('Content-Type'), 'application/json')
        ) {
            $format = 'json';
        }

        parent::findTemplate($request, $format, $code, $showException);
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您也可以通过使用kernel.exception事件来自己创建异常侦听器以进行进一步的控制。

如果您使用 FOSRestBundle,会尝试使用标头和格式优先级配置通过侦听器为您确定请求格式。Request Accept如果您使用此捆绑包,您可能能够避免自定义编码并仅依赖它。