我已将 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
我在 Controller 上有这个:
namespace PDI\PDOneBundle\Controller\Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\Annotations\Get;
class RepresentativeRestController extends FOSRestController
{
/**
* 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")
*/
public function getRepsAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('PDOneBundle:Representative')->findAll();
if(!$entities)
{
return $this->view(null, 400);
}
return $this->view($entities, 200);
}
}
但是当我尝试以下 URL app_dev.php/api/v1/reps 时,我收到了这个错误:
Unable to find template "". 500 Internal Server Error - InvalidArgumentException 3 linked Exceptions: Twig_Error_Loader » 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"
}
FOSRestBundle 没有配置返回 JSON 吗?为什么还要求 Twig 模板?我该如何解决这个问题?
第一次测试:
正如@Jeet 建议我尝试使用 Postman(与他告诉我的扩展相同)并在将 header Content-Type 设置为 application/json 之后错误变成了这个
Malformed JSON
因此,FOSRestBundle 没有按应有的方式设置 header , Controller 也没有返回有效的 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);
}
还是一样的问题:
Unable to find template "". 500 Internal Server Error - InvalidArgumentException 3 linked Exceptions: Twig_Error_Loader » 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 之类的工具并设置正确的 header ,客户端的请求肯定有问题,我得到了我想要的实体,请参见下图:
我找不到问题出在哪里,所以我在这里迫切需要别人的帮助,因为我已经没有主意了
最佳答案
正如大家所建议的:只有 Accept header 或扩展才能为您提供 JSON。似乎您已使用 Accept header 对此进行了排序。
为了使用扩展,你必须告诉你想如何在 Symfony 中设置格式。
这段代码应该给你一个你想要的输出:
namespace RestTestBundle\Controller;
use FOS\RestBundle\Controller\Annotations\View;
use FOS\RestBundle\Controller\Annotations\Get;
class YourController
{
/**
* @Get("/api/v1/reps.{_format}", defaults={"_format"="json"})
* @View()
*/
public function indexAction()
{
return array(
'status' => 'ok',
'companies' => array(
array('id' => 5),
array('id' => 7),
),
);
}
}
Edit1:如果你不想使用 View 类,而是纯数组:不要忘记禁止 SensioExtraBundle 的 View 处理
sensio_framework_extra:
view: { annotations: false }
Edit2:如果你不使用 HTML 格式,只想有一个 json 输出,你可以使用这样的配置:
fos_rest:
# ....
format_listener:
rules:
- { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }
# ....
解释为什么您看到错误“未找到 View ”:
TL;DR:您的浏览器发送一个 Accept header ,告诉 FOSRestBundle 输出“html”变体。
背景:该包主要与 Accept header 一起使用,最好使用所有可用的输出格式:html(您可以使用您提供的表单、对象列表、对象的详细信息轻松测试您的 REST API,这种方式很容易), json, xml.有时甚至图像 mime 类型,如默认的 image/jpeg、image/png 或作为变体的 json/xml(您可以使用 base64 图像表示)。
说明:如果您打开浏览器的“网络”选项卡并查看它发送的 header ,您会注意到类似这样的内容:text/html,application/xhtml+xml,application/xml;q=0.9, */*;q=0.8 意思是“按这样的顺序使用”:
如果仔细观察,您会发现根据您的配置 text/html 是您的配置具有 ('html') 和 */* 是另一个('json'),但是 text/html 的优先级为 1,而 */* 的优先级为 0.8,所以 text/html 匹配且 FOSRestBundle 尝试查找 HTML 表示但失败。
PS:如果您多次发布问题 - 请确保您关注每个线程中的所有回复。
关于php - FOSRestBundle 设置返回 JSON 但仍然要求 Twig 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114152/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出