joipolloi / json-validation-bundle
此包提供了一种验证请求中传递的JSON与模式的方法
Requires
- justinrainbow/json-schema: ^5.2
- sensio/framework-extra-bundle: >=3.0
- symfony/config: ^3.2
- symfony/http-foundation: ^3.2
This package is not auto-updated.
Last update: 2024-09-29 02:24:53 UTC
README
这是一个 Symfony 扩展包,提供了用于验证控制器动作接收的JSON与模式匹配的注解。
用法
当创建一个接受JSON输入的控制器方法(例如POST方法)时,将 @ValidateJson
注解应用于您的动作,并指向要验证的模式。
use JoiPolloi\Bundle\JsonValidationBundle\Annotation\ValidateJson class MyController { /** * @ValidateJson("@MyBundle/Resources/schema/action-schema.json") */ public function myAction() { // ... } }
现在每次调用动作时,传递的JSON都会与模式进行验证。如果没有验证错误,动作将正常执行。如果有错误,则返回400(错误请求)响应。
安装
使用composer: composer require joipolloi/json-validation-bundle
打开您的 Symfony 项目的 AppKernel.php
$bundles = array( // ... new JoiPolloi\Bundle\JsonValidationBundle\JsonValidationBundle(), // ... );
配置
唯一的配置选项是是否启用应用程序的问题+JSON事件监听器。这将在下面详细说明,默认为关闭,但可以通过以下配置在您的 config.yml 中启用
joipolloi_jsonvalidation: enable_problemjson_listener: true
详细信息
幕后,此扩展包在 kernel.controller
事件上注册了一个事件监听器,该监听器将使用 justinrainbow/json-schema 库验证请求内容(即 $request->getContent();
)是否与JSON模式匹配。
如果在定位JSON模式、解码JSON、解码JSON模式或验证JSON时出现问题,将抛出一个 JsonValidationException(它扩展了 BadRequestHttpException),并带有错误消息。
选项
获取有效的JSON
为了节省时间和处理时间,您可以通过获取请求上的 validJson
属性或通过将 $validJson
作为动作的参数来获取已验证的JSON作为一个对象。
/** * @ValidateJson("@MyBundle/Resources/schema/action-schema.json") */ public function myAction(Request $request, $validJson) { // $request->attributes->get('validJson') === $validJson }
如果您想以关联数组的形式获取解码的JSON或使用 Symfony 表单组件,请将 $validJson
的类型提示为数组。
/** * @ValidateJson("@MyBundle/Resources/schema/action-schema.json") */ public function myAction(array $validJson) { $form = $this->createForm(MyFormType::class); $form->submit($validJson); if ($form->isValid()) { // ... } }
这会带来轻微的性能开销,因为与获取对象相比,JSON需要解码两次:一次用于与JSON模式进行验证,另一次用于关联数组。如果您的JSON很大但只有单层深度,则通过直接转换为数组可能获得更好的性能。
public function myAction($validJson) { // ... $form->submit((array)$validJson); }
指定要验证的HTTP方法
如果您的控制器动作监听多个HTTP方法(例如PUT和POST),并且您只想在其中一个上验证JSON,则可以使用注解的 methods
参数。
/** * @ValidateJson("@MyBundle/Resources/schema/action-schema.json", methods={"POST"}) */ public function myAction(Request $request, $validJson = null) { if ($request->isMethod('POST')) { // $validJson !== null } }
允许空值为有效值
如果您出于某种原因想要允许空内容也是有效的,请使用注解的 emptyIsValid
参数。
/** * @ValidateJson("@MyBundle/Resources/schema/action-schema.json", emptyIsValid=true) */ public function myAction($validJson = null) { // ... }
请注意,只有空请求内容才会被视为有效;如果传递的是空但语法有效的JSON,它仍然会与模式进行验证(即 "{}" 不会被视为空)。
application/problem+json 响应
包中包含了一个异常监听器,它可以按照RFC 7807的详细说明发送一个application/problem+json
响应。[链接](https://tools.ietf.org/html/rfc7807)。默认情况下,监听器是关闭的,以允许您自己的应用程序处理异常,但可以通过在您的config.yml文件中进行配置来开启。
joipolloi_jsonvalidation: enable_problemjson_listener: true
如果监听器被禁用,则会抛出一个400 bad request异常,并由您的应用程序捕获。如果开启并且JSON解码或验证存在问题,响应可能如下所示:
{ "status": 400, "title": "Unable to parse\/validate JSON", "detail": "There was a problem with the JSON that was sent with the request", "errors": [ { "message": "[4] Syntax error" } ] }
"errors"键将至少是一个错误数组。每个错误将至少包含一个"message"键,但还可以包含包含有用信息的"constraint"、"pointer"和"property"键。
尽管此数组中的错误可以安全地发送回客户端,但关于路径的信息可能存在泄露风险 - 无论是到模式还是引用文件。如果有疑问,请禁用监听器并自行实现以获得更多控制。