原文出处:3-listener-support.md
原文作者:FriendsOfSymfony
授权许可:创作共用协议
翻译人员:FireHare
校对人员:
适用版本:FOSRestBundle 0.12.0
文章状态:草译阶段
Step 3: Listener support
Listeners are a way to hook into the request handling. This Bundle provides various events from decoding the request content in the request (body listener), determining the correct response format (format listener), reading parameters from the request(parameter fetcher listener), to formatting the response either with a template engine like twig or to f.e. xml or json using a serializer (view response listener)) as well as automatically setting the accepted http methods in the response (accept listener).
监听器是勾进请求处理的一种途径。本功能包提供从请求中解码请求内容(body监听器)、确定当前响应格式(格式监听器)、从请求中读取参数(参数提取监听器),到象twig这样的模板引擎或者使用序列化器生成xml或json来格式化响应(视图响应监听器)以及在响应中自动设置接收http方法(接受监听器)的不同的事件。
With this in mind we now turn to explain each one of them.
接下来,我们将逐个对其进行说明:
All listeners except the mime_type
one are disabled by default. You can enable one or more of these listeners. For example, below you can see how to enable all listeners:
在缺省状态下,所有监听器除了mime_type之外都被禁用。您可以启用其中的一个或更多。例如,下面您就可以看到如何启用使用监听器:
# app/config/config.yml fos_rest: param_fetcher_listener: true body_listener: true format_listener: true view: view_response_listener: 'force'
View Response listener(视图响应监听器)
The view response listener makes it possible to simply return a View
instance from action controllers. The final output will then automatically be processed via the listener by the fos_rest.view_handler
service.
视图响应监听器可以简单地从控制器Action中返回View实例。然后最终输出将通过 fos_rest.view_handler
服务自动监听处理。
This requires adding the SensioFrameworkExtraBundle to your vendors:
该功能要求在您的vendors中添加SensioFrameworkExtraBundle功能包:
http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html
Now inside a controller its possible to simply return a View
instance.
现在控制器中可以简单地返回View实例了。
setData($data); return $view; } }
As this feature is heavily based on the SensioFrameworkBundle, the example can further be simplified by using the various annotations supported by that bundle. There is also one additional annotation called @View()
which extends from the @Template()
annotation.
由于该特性很大程度上基于 SensioFrameworkBundle功能包,因此通过使用该功能包支持的不同注释,上述示例还可以进一步简化。这里还有一个从 @Template()
注释扩展的 @View()
注释。
The @View()
and @Template()
annotations behave essentially the samewith a minor difference. When view_response_listener
is set to true
instead of force
and @View()
is not used, then rendering will be delegated to SensioFrameworkExtraBundle.
@View()
和 @Template()
注释作用基本相同,仅有细微的差别。当 view_response_listener
设置为 true 而不是 force,同时 @View()
也没被使用,那么渲染将被委派给SensioFrameworkExtraBundle功能包。
Note that it is necessary to disable view annotations in SensioFrameworkExtraBundle so that FOSRestBundle can take over the handling.
注意这需要禁用SensioFrameworkExtraBundle功能包中的view注释,以便 FOSRestBundle 功能包可以接管该处理。
# app/config/config.yml
fos_rest:
view:
view_response_listener: force
sensio_framework_extra:
view: { annotations: false }
router: { annotations: true }
If @View()
is used, the template variable name used to render templating formats can be configured (default 'data'
):
如果使用 @View()
注释,那么模板变量名可以被配置用于渲染模板格式(缺省为'data'):
The status code of the view can also be configured:
视图的状态码也可以被配置:
The groups for the serializer can be configured as follows:
如下所示,序列化器组也可以被配置:
See the following example code for more details:
更多细节请参见下面示例代码:
https://github.com/liip/LiipHelloBundle/blob/master/Controller/ExtraController.php
Body listener(Body监听器)
The Request body decoding listener makes it possible to decode the contents of a request in order to populate the "request" parameter bag of the Request. This for example allows to receive data that normally would be sent via POST as
application/x-www-form-url encode
in a different format (for example application/json) in a PUT.请求体解码监听器使得解码请求内容并将其填充到Request请求参数包成为可能。例如,它可以允许正常情况下以
application/x-www-form-url
方式编码,通过POST发送的数据能够以不同的编码方式(如application/json)通过PUT发送。
You can add a decoder for a custom format. You can also replace the default decoder services provided by the bundle for the
json
andxml
formats.Below you can see how to override the decoder for the json format (the xml decoder is explicitly kept to its default service):您可以为定制的格式添加×××。您也可以替换通过功能包为json和xml格式提供的缺省的×××服务。接下来您将看到如何为json格式覆写×××(xml×××则明确确定为其缺省服务):
# app/config/config.yml fos_rest: body_listener: decoders: json: acme.decoder.json xml: fos_rest.decoder.xmlYour custom decoder service must use a class that implements the
FOS\Rest\Decoder\DecoderInterface
.您自定义的×××服务必须使用实现了
FOS\Rest\Decoder\DecoderInterface
接口的类。
If you want to be able to use form with checkbox and have true and false value (without any issue) you have to use : fos_rest.decoder.jsontoform (available since fosrest 0.8.0)
如果您想使用带复选框的表单,并产生 true 和 false 值(这没任何问题),您将不得不使用:fos_rest.decoder.jsontoform(该功能在 fosrest 0.8.0版本之后启用)。
Request Body Converter Listener(请求体转换监听器)
Converters are a way to populate objects and inject them as controller method arguments.The Request body converter makes it possible to deserialize the request body into an object.
转换器是填充对象并将其作为控制器方法参数注入的一种方式。请求体转换使得将请求体反序列化为对象成为可能。
This converter requires that you have installed SensioFrameworkExtraBundle and have the converters enabled:
该转换器要求您安装 SensioFrameworkExtraBundle 功能包并启用转换器功能:
# app/config/config.yml sensio_framework_extra: request: { converters: true }To enable the Request body converter, add the following configuration:
要启用请求体转换,还需要添加下列配置:
# app/config/config.yml fos_rest: body_converter: enabled: trueNote: You will probably want to disable the automatic route generation (
@NoRoute
)for routes using the body converter, and instead define the routes manually to avoid having the deserialized, type hinted objects ($post in this example
) appearin the route as a parameter.注意:在使用body转换时,您可能希望禁用自动路由生成功能(
@NoRoute
),而手工设置路由以避免反序列化的、类型暗示对象(在本例中是$post)作为参数出现在路由里。
Now, in the following example, the request body will be deserialized into a new instance of
Post
and injected into the$post
variable:现在,在下面的例子里,请求体将被反序列化到一个新的Post示例中,并将其注入到$post变量中:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; // ... /** * @ParamConverter("post", converter="fos_rest.request_body") */ public function putPostAction(Post $post) { // ... }You can configure the context used by the serializer during deserialization via the
deserializationContext
option:在通过
deserializationContext
选项进行反序列化期间,您可以通过序列化器来配置上下文:/** * @ParamConverter("post", converter="fos_rest.request_body", options={"deserializationContext"={"groups"={"group1", "group2"}, "version"="1.0"}}) */ public function putPostAction(Post $post) { // ... }Validation(验证)
If you would like to validate the deserialized object, you can do so by enabling validation:
如果您想验证反序列对象,您可以通过启用验证功能来实现:
# app/config/config.yml fos_rest: body_converter: enabled: true validate: true validation_errors_argument: validationErrors # This is the default valueThe validation errors will be set on the
validationErrors
controller argument:验证错误将被设置在控制器参数
validationErrors
上/** * @ParamConverter("post", converter="fos_rest.request_body") */ public function putPostAction(Post $post, ConstraintViolationListInterface $validationErrors) { if (count($validationErrors) > 0) { // Handle validation errors } // ... }Format listener(格式监听器)
The Request format listener attempts to determine the best format for the request based on the Request's Accept-Header and the format priority configuration. This way it becomes possible to leverage Accept-Headers to determine the request format, rather than a file extension (like foo.json).
请求格式监听器基于Request的接收头和格式的优先级配置来尝试确定最佳格式。这种方式可以利用接收头来确定请求格式,而非文件扩展名(如foo.json)。
The
default_priorities
define the order of formats as the application prefers. The algorithm iteratively examines the provided Accept header first looking at all the options with the highestq
. The first priority that matches is returned. If none match the next lowest set of Accept headers with equalq
is examined and so on until there are no more Accept headers to check. In this casefallback_format
is used.
default_priorities
定义了应用程序偏好的格式顺序。该算法抚今迭代检查所提供的接收头,首先查找所有具有最高q
的选项,第一优先匹配返回。如果没有匹配,则检查下一个有着相同q
的最低接收头,直到没有接收头检查。在这种格式下使用fallback_format
Note that if
_format
is matched inside the route, then a virtual Acceptheader setting is added with aq
setting one lower than the lowest Acceptheader, meaning that format is checked for a match in the priorities last. Ifprefer_extension
is set totrue
then the virtual Accept header will be one higher than the highestq
causing the extension to be checked first.注意, if
_format
在路由中匹配,那么将添加一个虚拟接收头设置,该设置有着比最低接收头更低的 q 设置,这就意味着该格式将是最后优先级匹配。如果prefer_extension
设置为 true,那么虚拟接收头将比最高的q
还高,这将引起扩展将被最先检查。
Note that setting
default_priorities
to a non empty array enables Accept header negotiations, while adding '*/*' to the priorities will effectively cause any priority to match.注意将
default_priorities
设置为非空数组,将启用接收头协商,这时添加到优先级中的'*/*'是有效的,它将匹配任何优先级。# app/config/config.yml fos_rest: format_listener: default_priorities: ['json', html, '*/*'] fallback_format: json prefer_extension: trueFor example using the above configuration and the following Accept header:
例如使用上述配置及下列接收头:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/jsonAnd the following route:
以及以下路由:
hello: pattern: /foo.{_format} defaults: { _controller: foo.controller:indexAction, _format: ~ }When calling:
当调用:
/foo
will lead to setting the request format tojson
/foo 将导致设置请求格式为json
/foo.html
will lead to setting the request format tohtml
/foo.html 将导致设置请求格式为html
Note that the format needs to either be supported by the Request
class natively or it needs to be added as documented here:
注意在这里格式需要被Request类自身支持,也需要在下面文档记录才被添加:
http://symfony.com/doc/current/cookbook/request/mime_type.html
Mime type listener(Mime类型监听器)
This listener allows registering additional mime types in the Request
class. It works similar to the following cookbook entry:
该监听器允许在Request类中注册额外的Mime类型。它的工作原理与下面食谱项相似:
http://symfony.com/doc/current/cookbook/request/mime_type.html
Param fetcher listener(参数提取监听器)
The param fetcher listener simply sets the ParamFetcher instance as a request attributeconfigured for the matched controller so that the user does not need to do this manually.
参数提取监听器为匹配控制器的请求属性配置而简单设置ParamFetcher实例,而无须用户手动设置。
# app/config/config.yml fos_rest: param_fetcher_listener: true
get('page'); $articles = array('bim', 'bam', 'bingo'); return array('articles' => $articles, 'page' => $page); }
Note: There is also $paramFetcher->all()
to fetch all configured query parameters at once. And also both $paramFetcher->get()
and $paramFetcher->all()
support and optional $strict
parameter to throw a \RuntimeException
on a validation error.
注意:这里还可以使用 $paramFetcher->all()
一次性获取所有配置的查询参数。它支持 $paramFetcher->get()
和 $paramFetcher->all()
两种方式,同时可选参数 $strict
将在验证错误时抛出\RuntimeException
异常。
Optionally the listener can also already set all configured query parameters as request attributes
可选的监听器也已经设置了所有配置的查询参数作为请求属性。
# app/config/config.yml fos_rest: param_fetcher_listener: force
$articles, 'page' => $page); }
Allowed Http Methods Listener(允许的HTTP方法监听器)
This listener add the Allow
HTTP header to each request appending all allowed methods for a given resource.
对于给定资源,本监听器添加允许HTTP头,允许每个请求附加所有被允许的方法。
Let's say we have the following routes:
比方说我们有以下路由:
api_get_users api_post_users api_get_user
A GET
request to api_get_users
will response in:
一个 GET
发送到 api_get_users
的请求将被响应:
< HTTP/1.0 200 OK < Date: Sat, 16 Jun 2012 15:17:22 GMT < Server: Apache/2.2.22 (Ubuntu) < allow: GET, POST
You need to enable this listener like this as it is disabled by default:
您需要象这样启用该监听器,因为它在缺省状态下是被禁用的:
fos_rest: allowed_methods_listener: true
Security Exception Listener(安全异常监听器)
By default it is the responsibility of firewall access points to deal with AccessDeniedExceptions.For example the form
entry point will redirect to the login page. However for a RESTful application proper response HTTP status codes should be provided. This listener is triggered before the normal exception listener and firewall entry points and forces returning either a 403 or 401 status code for any of the formats configured.
缺省状态下,防火墙访问点负责处理AccessDeniedExceptions。例如表单接入点将重定向到 登录页面。然而在REST风格的应用程序中将提供适当HTTP状态码。该监听器在正常异常监听器和防火墙访问点之前被触发,并为任何格式配置强制返回403或401状态码。
It will return 401 for Symfony\Component\Security\Core\Exception\AuthenticationException
or 403 forSymfony\Component\Security\Core\Exception\AccessDeniedException
.
它将为Symfony\Component\Security\Core\Exception\AuthenticationException
返回401,或者为Symfony\Component\Security\Core\Exception\AccessDeniedException
返回403。
You need to enable this listener like this as it is disabled by default:
您需要象这样启用该监听器,因为它在缺省状态下是被禁用的:
fos_rest: access_denied_listener: # all requests using the 'json' format will return a 403 on an access denied violation json: true
It is also recommended to enable the exception controller described in the next chapter.
建议启用异常控制器,这将在下一章节说明。
That was it!
Return to the index or continue reading about ExceptionController support.
返回指南页或继续阅读异常控制器支持