我试图让我的自定义json错误模板由Symfony返回,但它不断返回HTML版本。使用休息客户端我已将 接受 和 内容类型 设置为" application / json&#34 ;但只返回error404.html.twig的内容,而不是error404.json.twig文件。
目前我通过一个完全无效的URL(即没有路由)对此进行测试,但是一旦我开始工作,我也会将其用于有效的URL,这些URL不会导致资源,并且内部代码会抛出一个HttpNotFoundException
答案 0 :(得分:4)
在您的请求上设置标题实际上不会对返回的错误模板产生任何影响,尽管看起来这可能是逻辑路径。生成的错误模板基于请求格式,该格式可以在_format
参数中设置,也可以在Request
对象本身上手动设置。 this post中有一个解决方案,但是如果您收到404错误,则无法从没有路由的Controller中设置_format
参数或$request->setRequestFormat('json')
调用。
Symfony拥有非常好的文档how to customize error pages,包括您可能想要采用的路径,overriding the default ExceptionController
。基本上,您会覆盖showAction()
或findTemplate()
方法,该方法需要Accept
标头并检查application/json
。您还可以检查Content-Type
标头作为附加要求。所以这里是你的听众的声明:
# app/config/services.yml
services:
app.exception_controller:
class: AppBundle\Controller\CustomExceptionController
arguments: ['@twig', '%kernel.debug%']
然后设置Twig参数:
# app/config/config.yml
twig:
exception_controller: app.exception_controller:showAction
现在定义您的课程并覆盖您需要的相关部分。第一个示例通过检查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);
}
}
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);
}
}
当然,您也可以working with the kernel.exception
event自己创建一个异常监听器,以便进一步控制。
如果您使用FOSRestBundle,它会使用Request
Accept
标头和格式优先级配置通过侦听器尝试determine the request format for you。如果您使用此捆绑包,您可能可以避免自定义编码,只需依靠它。