Php FOSRestBundle设置返回JSON,但仍要求提供细枝模板

Php FOSRestBundle设置返回JSON,但仍要求提供细枝模板,php,json,symfony,fosrestbundle,symfony-2.6,Php,Json,Symfony,Fosrestbundle,Symfony 2.6,我已将FOSRestBundle配置如下: #FOSRestBundle fos_rest: param_fetcher_listener: true body_listener: true format_listener: rules: - { path: ^/, priorities: [ json, html ], fallback_format: ~, prefer_extension: true } med

我已将FOSRestBundle配置如下:

#FOSRestBundle
fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener:
        rules:
            - { path: ^/, priorities: [ json, html ], fallback_format: ~, prefer_extension: true }
        media_type:
            version_regex: '/(v|version)=(?P<version>[0-9\.]+)/'

    body_converter:
        enabled: true
        validate: true

    view:
        mime_types:
            json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1']
        view_response_listener: 'force'
        formats:
            xml:  false
            json: true
        templating_formats:
            html: true

    exception:
        codes:
            'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404
            'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT
        messages:
            'Symfony\Component\Routing\Exception\ResourceNotFoundException': true
    allowed_methods_listener: true
    access_denied_listener:
        json: true
但是当我尝试以下URL
app_dev.php/api/v1/reps
时,我得到了这个错误:

找不到模板“”。500内部服务器错误- InvalidArgumentException 3链接异常:细枝错误加载程序» InvalidArgumentException»InvalidArgumentException»

我希望API返回格式良好的JSON,如下例所示:

{
   "id":"30000001",
   "veeva_rep_id":"0055648764067SwzAAE",
   "display_name":"John Know",
   "avatar_url":"http://freelanceme.net/Images/default%20profile%20picture.png",
   "rep_type":"VEEVA",
   "username":"john@mail.com",
   "first":"John",
   "last":"Know",
   "title":"Sales Representative",
   "phone":"800-555-1212",
   "email":"john@mail.com",
   "territory_id":"200454001",
   "inactive":"no",
   "total_contacts":"6",
   "total_shares":"0",
   "totalViews":"0",
   "lastLoginAt":"2015-05-05 15:45:57",
   "lastVeevaSyncAt":"2015-05-05 15:45:57",
   "createdAt":"2015-05-05 15:45:57",
   "updatedAt":"2015-05-05 15:45:57"
}
是否为返回JSON配置了FOSRestBundle?为什么还要求提供细枝模板?我怎样才能解决这个问题

第一次测试:

正如@Jeet建议我的那样,我尝试过使用Postman(与他告诉我的扩展名相同),在将标题
Content-Type
设置为
application/json
后,错误会变成这样

格式错误的JSON

因此,FOSRestBundle没有按应有的方式设置头,控制器也没有返回有效的JSON,如何修复这些头

第二次测试:

根据@Jeet的建议,我运行此测试:

/**
 * Get all representatives.
 *
 * @return array
 *
 * @ApiDoc(
 *   resource = true,
 *       https = true,
 *   description = "Get all representatives.",
 *   statusCodes = {
 *      200 = "Returned when successful",
 *      400 = "Returned when errors"
 *   }
 * )
 * @Get("/api/v1/reps")
 * @View()
 */
public function getRepsAction()
{
    $em = $this->getDoctrine()->getManager();
    $entities = $em->getRepository('PDOneBundle:Representative')->findAll();

    $temp = array("1", "2", "3");

    $view = $this->view($temp, Codes::HTTP_OK);
    return $this->handleView($view);
}
还是同样的问题:

找不到模板“”。500内部服务器错误- InvalidArgumentException 3链接异常:细枝错误加载程序» InvalidArgumentException»InvalidArgumentException»

这里还有什么不对劲?我是不是在配置上遗漏了什么

一开始我忘了添加
app/config/routing.yml
src/PDI/PDOneBundle/Resources/config/routing.yml
,所以他们来了,也许这是拼图上缺少的部分,让你更好地了解问题的来源:

#app/config/routing.yml
#PDOne
pdone:
    resource: "@PDOneBundle/Resources/config/routing.yml"

template:
    resource: "@TemplateBundle/Resources/config/routing.yml"

#FOSUserBundle
fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"
    prefix: /

#NelmioApiDocBundle:
NelmioApiDocBundle:
    resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
    prefix:   /api/doc

#SonataAdmin
admin:
    resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
    prefix: /admin

_sonata_admin:
    resource: .
    type: sonata_admin
    prefix: /admin

#src/PDI/PDOneBundle/Resources/config/routing.yml
pdone:
    resource: "@PDOneBundle/Controller/"
    type:     annotation
    prefix:   /
第三次测试:

客户端的请求肯定有问题,如果我使用像
Postman
这样的工具并设置适当的标题,我得到了想要的实体,请参见下图:


我找不到问题出在哪里,所以我在这里非常需要别人的帮助,因为我已经没有主意了

FosRestBundle利用了Accept头。这意味着它将根据您的请求返回响应。通过访问路径“app_dev.php/api/v1/reps”,您隐式地请求html格式,因此它尝试提供一个模板

app_dev.php/api/v1/reps.json是否返回您需要的内容


您还应该测试app_dev.php/api/v1/reps.xml,并期望得到一个xml输出。您可以通过两种方式给出响应

return View::create($entities, Codes::HTTP_OK);


正如guys所建议的:只有Accept头或扩展才能提供JSON。看起来您已经用Accept标题对其进行了排序

为了使用扩展,您必须说明如何在Symfony中设置格式

此代码应为您提供所需的输出:

namespace restestbundle\Controller;
使用FOS\RestBundle\Controller\Annotations\View;
使用FOS\RestBundle\Controller\Annotations\Get;
类控制器
{
/**
*@Get(“/api/v1/reps.{u-format}”,默认值={{u-format=“json”})
*@View()
*/
公共函数索引()
{
返回数组(
“状态”=>“正常”,
“公司”=>数组(
数组('id'=>5),
数组('id'=>7),
),
);
}
}
Edit1:如果您不想使用
视图
类,而是纯数组:不要忘记禁止对SensioExtraBundle进行视图处理

sensio\u框架\u额外:
视图:{注释:false}
Edit2:如果您不使用HTML格式,只希望有json输出,则可以使用以下配置:

fos\u rest:
# ....
格式\u侦听器:
规则:
-{path:^/,priorities:[json],回退\格式:json,首选\扩展名:true}
# ....
解释您看到错误“未找到视图”的原因:

TL;DR:您的浏览器发送一个接受头,告诉FOSRestBundle输出一个“html”变体

背景:此捆绑包主要与Accept头一起工作,拥有所有可用的输出格式是一个很好的实践:html(您可以使用您提供的表单、对象列表、对象详细信息轻松地测试RESTAPI)、json、xml。有时甚至图像mime类型,如默认的image/jpeg、image/png或作为变体的json/xml(您可以使用base64图像表示)

说明:如果您打开浏览器的“网络”选项卡并查看它发送的标题,您将注意到如下内容:
text/html、application/xhtml+xml、application/xml;q=0.9,*/*;q=0.8
表示“按此顺序使用”:

  • 文本/html
  • application/xhtml+xml
  • 优先级为0.9的application/xml,根据您的配置,这是禁止的
  • */*优先级为0.8,表示任何格式
  • 如果您仔细观察这一点,您会发现,根据您的配置,text/html是配置中的一个变体(“html”),而*/*是另一个变体(“json”),但text/html的优先级为1,而*/*的优先级为0.8,因此text/html匹配,而FOSRestBundle尝试查找html表示,但失败了

    注:如果您多次发布问题-请确保您注意每个帖子中的所有回复。

    您可以简单地使用

                $view = new View($form);
                $view->setFormat('json');
                return $this->handleView($view);
    

    您是否已将“内容类型”设置为“application/json”?@Jeet我应该在哪里进行设置?没有在OP上看到的FOSRes配置?在Google Chrome的高级Rest客户端应用程序(应用程序扩展)中尝试app_dev.php/api/v1/reps,您将有一个选项。@Jeet看到OP,我编辑了添加一些信息
    FOSRestBundle
    负责为发送给客户端的响应设置标题。但它的客户端(移动应用程序、REST客户端扩展)有责任在将其发送到服务器时设置正确的头值。
    FOSRestBundle
    可以相应地响应。;)这三种方法对我都不起作用,当我把
    .html
    .json
    .xml
    放到404路由错误中时,我找不到我缺少的东西
    $view = $this->view($entities, Codes::HTTP_OK);    
    return $this->handleView($view)
    
                $view = new View($form);
                $view->setFormat('json');
                return $this->handleView($view);