我需要在symfony 2上为我的网站实现RESTful API,所以我使用FOSRestBundle + JMSSerializerBundle
我的实体有这样的序列化器yml:
Acme\DemoBundle\Entity\Product:
exclusion_policy: ALL
accessor_order: custom
custom_accessor_order: [id, title]
properties:
id:
expose: true
title:
expose: true
virtual_properties:
getMainPhoto:
serialized_name: photo
Run Code Online (Sandbox Code Playgroud)
问题是getMainPhoto返回我的网址到完整大小的图像.我希望在向api客户端发送响应之前预处理此URL,我可以生成新的url来调整此类映像的大小.我已经在sf2中有服务可以完成这项工作:
$resized_url = $someService->generateResizedUrl($item->getMainPhoto(), 640, 480);
Run Code Online (Sandbox Code Playgroud)
但我不知道如何在JMSSerializer中使用此服务.也许在发送响应之前有一些FOSRestBundle\JMSSerializerBundle的回调?
成功将json字符串反序列化为具有关联的Doctrine实体后.在持久化时,Doctrine始终将这些关联检测为"新实体".如何仅通过ID更新关联,如果有任何更改,则不更改相关实体值?
我的情况:
我有一些带有静态数据的数据库表.最简单的是存储单位.(我有一个名为Unit的学说实体).表格是这样的:
|id|name |ratio |
|1 |mgr |1 |
|2 |gr |1000 |
|3 |Kgr |1000000|
Run Code Online (Sandbox Code Playgroud)
然后,用户可以创建一个Item,它也有一个名为Unit的服务器端学说实体.我使用客户端backbone.js模型,并在更新时将其发送到我的Symfony2应用程序,如下所示:
//Item object to be serialized into Item entity
{
id: 13141
weight: 100
unit: {
id:1
name:mgr
ratio:1
}
//many more attributes here
}
Run Code Online (Sandbox Code Playgroud)
现在,我使用JMSSerializer进行反序列化,一切正常,但我希望doctrine只更新关系的Unit ID,而不是整个Unit.
当我坚持下去时,教义抱怨并告诉我他找到了一个"新的单位实体"(这不是我想要的)并告诉我persist在学说实体中设置级联.但是,如果我这样做并且某人修改了单位json,那么这不会改变我的静态单位表吗?
例如:坏用户通过发送以下内容来修改Json:
//BAD item object to be serialized into Item entity
{
id: 13141
weight: 100
unit: {
id:1
name:BadName //Will this get persisted to the database?
ratio:1
}
//many more attributes here
} …Run Code Online (Sandbox Code Playgroud) 尝试序列化使用特征的模型时,JMSSerializer不会序列化该特征包含的属性.我使用yaml来配置序列化程序,但它似乎无法正常工作.
trait IdentityTrait
{
protected $id;
public function setId($id)
{
$this->id = $id;
return $this;
}
public function getId()
{
return $this->id;
}
}
class OurClass {
use IdentityTrait;
protected $test;
public function getTest() {
$this->test;
}
}
Run Code Online (Sandbox Code Playgroud)
使用JMSSerializerBundle并且以下yaml位于 Resources/config/serializer/Model.Traits.IdentityTrait.yml
MyProject\Component\Core\Model\Traits\IdentityTrait:
exclusion_policy: NONE
properties:
id:
expose: true
Run Code Online (Sandbox Code Playgroud)
而OurClass配置位于Resources/config/serializer/Model.OurClass.yml
MyProject\Component\Core\Model\OurClass:
exclusion_policy: NONE
properties:
test:
expose: true
Run Code Online (Sandbox Code Playgroud)
一些代码被忽略以专注于该问题
我发现了许多关于使用FOSRest进行部分API响应的问题,所有答案都基于JMS序列化程序选项(exlude,include,groups等).它工作正常,但我试图实现一些不那么"静态"的东西.
假设我有一个具有以下属性的用户: id username firstname lastname age sex
我使用端点GET /users/{id}和以下方法检索此用户:
/**
* @View
*
* GET /users/{id}
* @param integer $user (uses ParamConverter)
*/
public function getUserAction(User $user) {
return $user;
}
Run Code Online (Sandbox Code Playgroud)
该方法返回用户的所有属性.
现在我想允许这样的事情: GET /users/{id}?attributes=id,username,sex
我是否错过了FOSRestBUndle,JMSserializer或SensioFrameworkExtraBundle的功能来自动实现它?请求中的注释,方法,关键字或其他内容?
否则,实现它的最佳方法是什么?
我想做类似的事情:
/**
* @View
* @QueryParam(name="attributes")
*
* GET /users/{id}
*
* @param integer $user (uses ParamConverter)
*/
public function getUserAction(User $user, $attributes) {
$groups = $attributes ? explode(",", $attributes) : array("Default");
$view = $this->view($user, 200)
->setSerializationContext(SerializationContext::create()->setGroups($groups)); …Run Code Online (Sandbox Code Playgroud) 我正在使用JMS Serializer.当它与Doctrine ArrayCollection类型一起使用时,JsonSerializer给出了一个不正确的数组格式.指定的结果应遵循格式,[ {}, {} ]但它给了我{ 1: {}, 2: {} }.
有关此方案的其他信息.它只发生在我尝试序列化包含包含ArrayCollection的对象的对象并且ArrayCollection包含第一级对象时.例如:
{
"description":"Text provided",
"date":"1434145921000",
"oid":1,
"userCreator":{
"username":"name123",
"password":"psw",
"oid":2,
"name":"the-name",
"lastname":"the-lasname",
"announcements":{
"1":{
"description":"Clases de inglés",
"date":"1434745921000",
"oid":3
},
"2":{
"description":"Reparar ordenador",
"date":"1434145921000",
"oid":5
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我直接序列化用户实体,则不会发生这种情况:
{
"username":"user1",
"password":"123",
"oid":2,
"name":"Rafael",
"lastname":"Jimenez"
"announcements":[
{
"description":"Cargar cajas a la guardilla",
"date":"1434145921000",
"oid":1
},
{
"description":"Contar césped y quitar malas hierbas",
"date":"1434745921000",
"oid":3
},
{
"description":"Reparar ordenador",
"date":"1434145921000",
"oid":5
}
]
}
Run Code Online (Sandbox Code Playgroud)
任何线索?
我们使用Symfony2 FOSRestBundle和JMSSerializerBundle来开发移动开发人员使用的REST API.
JSON格式的API响应在适用的情况下返回"null"作为属性的值,这将为移动开发人员使用的第三方库生成例外.
我没有看到JMSSerializerBundle或FOSRestBundle的解决方案根据我们的要求覆盖该值.
到目前为止的解决方法 我可以在实体中设置默认值,以便新数据在数据库中具有一些默认值,而不是null.但这对于一对一/多对一关系对象不起作用,因为默认情况下它们将返回null而不是空白对象.
在序列化后覆盖json的任何解决方案?
我正在使用JMSSerializer来反序列化JSON请求,并且我遇到了ManyToOne关系的麻烦.我想从给定的id反序列化关系实体.例:
Class Game {
/**
* @var Team
*
* @ORM\ManyToOne(targetEntity="Team")
* @ORM\JoinColumn(name="home_team_id", referencedColumnName="id")
* @JMSSerializer\SerializedName("home")
*/
private $homeTeam;
/**
* @ORM\ManyToOne(targetEntity="Team")
* @ORM\JoinColumn(name="visitor_team_id", referencedColumnName="id")
* @JMSSerializer\SerializedName("visitor")
*/
private $visitorTeam;
}
Run Code Online (Sandbox Code Playgroud)
所以,当我得到这个Json
{"home":"id1","visitor":"id2"}
获取相关实体.任何云?我无法弄清楚
提前致谢
我收到这条消息:
Invalid datetime "2017-11-07T19:46:57.118Z", expected format Y-m-d\\TH:i:sP.
Run Code Online (Sandbox Code Playgroud)
使用JMS Serializer和配置时:
jms_serializer:
handlers:
datetime:
default_format: 'Y-m-d\\TH:i:sP'
Run Code Online (Sandbox Code Playgroud)
我认为我提供的日期格式正确,但显然没有.这是日期错了吗?
我有一个带有fos restbundle的Symfony rest api构建,我正在反序列化json PUT请求,以便更新具有to-many关系的doctrine实体.但是,配置的to-many子对象orphanremoval=true在json数据中不存在时不会从数据库中删除.
PUT请求有效负载:
{
"id": 1,
"name":"Some name",
"export_destinations": [
{
"id": 1,
"type": "USER_STORAGE",
"user": {"id": 5}
}
{
"id": 2,
"type": "SYSTEM_STORAGE"
}
]
}
Run Code Online (Sandbox Code Playgroud)
控制器动作:
/**
* @Rest\Put("{id}")
* @ParamConverter(
* "exportJob",
* converter="fos_rest.request_body",
* options={"deserializationContext"={"groups"={"put"}}}
* )
* @Rest\View(serializerGroups={"details"})
* @param ExportJob $exportJob
* @return ExportJob
*/
public function putAction(ExportJob $exportJob)
{
$this->getManager()->persist($exportJob);
$this->getManager()->flush();
return $exportJob;
}
Run Code Online (Sandbox Code Playgroud)
ExportJob实体
/**
* @ORM\Entity()
*/
class ExportJob
{
/**
* @var ArrayCollection|ExportDestination[]
*
* …Run Code Online (Sandbox Code Playgroud) 我想使用JMSSerializer处理序列化和反序列化的单个对象属性.我们有这个课:
class Task {
const STATUS_PENDING = 0;
const STATUS_OVER = 1;
protected $status;
/* getter and setter */
public function getStatusLabel()
{
return ['pending', 'over'][$this->getStatus()];
}
public static function getStatusFromLabel($label)
{
return [
'pending' => self::STATUS_PENDING,
'over' => self::STATUS_OVER
][$label];
}
}
Run Code Online (Sandbox Code Playgroud)
我想返回Task的实例抛出一个REST API(使用FOSRestBundle).问题是我不想返回$status属性的原始值,而是返回"label"值.
像这样配置我的序列化:
Task:
exclusion_policy: ALL
properties:
status:
expose: true
type: string
Run Code Online (Sandbox Code Playgroud)
JMS Serializer认为原始值为0或1,但我想在序列化对象中发送'pending'或'over'(using getStatusLabel).并且在反序列化(使用getStatusFromLabel)上执行相反的工作.
我认为virtual_properties它只是一个但是它只能用于治疗方向.
我尝试使用这样的自定义处理程序:
class TaskHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return [
[ …Run Code Online (Sandbox Code Playgroud) symfony ×8
doctrine ×2
json ×2
php ×2
api ×1
backbone.js ×1
doctrine-orm ×1
iso8601 ×1
symfony-2.8 ×1