2
0
mirror of https://github.com/oatpp/oatpp.git synced 2025-04-12 18:50:22 +08:00

Json serializer config. Optional null fields inclusion

This commit is contained in:
lganzzzo 2018-07-03 16:01:54 +03:00
parent bb1a4db399
commit fbf016107b
3 changed files with 123 additions and 112 deletions

@ -55,7 +55,7 @@ public:
void write(const std::shared_ptr<oatpp::data::stream::OutputStream>& stream,
const oatpp::data::mapping::type::AbstractObjectWrapper& variant) const override {
Serializer::serialize(stream, variant);
Serializer::serialize(stream, variant, serializerConfig);
}
oatpp::data::mapping::type::AbstractObjectWrapper

@ -30,62 +30,63 @@ namespace oatpp { namespace parser { namespace json { namespace mapping {
void Serializer::writeString(oatpp::data::stream::OutputStream* stream,
void* object,
Property* field) {
Property* field,
const std::shared_ptr<Config>& config) {
auto value = oatpp::data::mapping::type::static_wrapper_cast<oatpp::base::StrBuffer>(field->get(object));
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
if(!value){
stream->write("null", 4);
} else {
if(value) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
auto encodedValue = Utils::escapeString(value->getData(), value->getSize());
stream->writeChar('\"');
stream->write(encodedValue);
stream->writeChar('\"');
} else if(config->includeNullFields) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": null", 7);
}
}
void Serializer::writeObject(oatpp::data::stream::OutputStream* stream,
void* object,
Property* field){
Property* field,
const std::shared_ptr<Config>& config){
auto value = oatpp::data::mapping::type::static_wrapper_cast<Object>(field->get(object));
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
if(!value){
stream->write("null", 4);
} else {
writeObject(stream, field->type, value.get());
if(value) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
writeObject(stream, field->type, value.get(), config);
} else if(config->includeNullFields) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": null", 7);
}
}
void Serializer::writeListOfString(oatpp::data::stream::OutputStream* stream,
AbstractList* list){
AbstractList* list,
const std::shared_ptr<Config>& config){
stream->writeChar('[');
bool first = true;
auto curr = list->getFirstNode();
while(curr != nullptr){
auto value = oatpp::data::mapping::type::static_wrapper_cast<oatpp::base::StrBuffer>(curr->getData());
if(first){
first = false;
} else {
stream->write(", ", 2);
}
if(!value){
stream->write("null", 4);
} else {
if(value) {
(first) ? first = false : stream->write(", ", 2);
auto encodedValue = Utils::escapeString(value->getData(), value->getSize());
stream->writeChar('\"');
stream->write(encodedValue);
stream->writeChar('\"');
} else if(config->includeNullFields) {
(first) ? first = false : stream->write(", ", 2);
stream->write("null", 4);
}
curr = curr->getNext();
}
stream->writeChar(']');
@ -94,27 +95,24 @@ void Serializer::writeListOfString(oatpp::data::stream::OutputStream* stream,
void Serializer::writeListOfObject(oatpp::data::stream::OutputStream* stream,
AbstractList* list,
const Type* const type){
const Type* const type,
const std::shared_ptr<Config>& config){
stream->writeChar('[');
bool first = true;
auto curr = list->getFirstNode();
while(curr != nullptr){
auto value = oatpp::data::mapping::type::static_wrapper_cast<Object>(curr->getData());
if(first){
first = false;
} else {
stream->write(", ", 2);
}
if(!value){
if(value) {
(first) ? first = false : stream->write(", ", 2);
writeObject(stream, type, value.get(), config);
} else if(config->includeNullFields) {
(first) ? first = false : stream->write(", ", 2);
stream->write("null", 4);
} else {
writeObject(stream, type, value.get());
}
curr = curr->getNext();
}
stream->writeChar(']');
@ -123,27 +121,24 @@ void Serializer::writeListOfObject(oatpp::data::stream::OutputStream* stream,
void Serializer::writeListOfList(oatpp::data::stream::OutputStream* stream,
AbstractList* list,
const Type* const type){
const Type* const type,
const std::shared_ptr<Config>& config){
stream->writeChar('[');
bool first = true;
auto curr = list->getFirstNode();
while(curr != nullptr){
auto value = oatpp::data::mapping::type::static_wrapper_cast<AbstractList>(curr->getData());
if(first){
first = false;
} else {
stream->write(", ", 2);
}
if(!value){
if(value) {
(first) ? first = false : stream->write(", ", 2);
writeListCollection(stream, value.get(), type, config);
} else if(config->includeNullFields) {
(first) ? first = false : stream->write(", ", 2);
stream->write("null", 4);
} else {
writeListCollection(stream, value.get(), type);
}
curr = curr->getNext();
}
stream->writeChar(']');
@ -152,81 +147,86 @@ void Serializer::writeListOfList(oatpp::data::stream::OutputStream* stream,
void Serializer::writeListCollection(oatpp::data::stream::OutputStream* stream,
AbstractList* list,
const Type* const type){
const Type* const type,
const std::shared_ptr<Config>& config){
Type* itemType = *(type->params.begin());
auto itemTypeName = itemType->name;
if(itemTypeName == oatpp::data::mapping::type::__class::String::CLASS_NAME){
writeListOfString(stream, list);
writeListOfString(stream, list, config);
} else if(itemTypeName == oatpp::data::mapping::type::__class::Int32::CLASS_NAME) {
writeListOfSimpleData<oatpp::data::mapping::type::Int32::ObjectType>(stream, list);
writeListOfSimpleData<oatpp::data::mapping::type::Int32::ObjectType>(stream, list, config);
} else if(itemTypeName == oatpp::data::mapping::type::__class::Int64::CLASS_NAME) {
writeListOfSimpleData<oatpp::data::mapping::type::Int64::ObjectType>(stream, list);
writeListOfSimpleData<oatpp::data::mapping::type::Int64::ObjectType>(stream, list, config);
} else if(itemTypeName == oatpp::data::mapping::type::__class::Float32::CLASS_NAME) {
writeListOfSimpleData<oatpp::data::mapping::type::Float32::ObjectType>(stream, list);
writeListOfSimpleData<oatpp::data::mapping::type::Float32::ObjectType>(stream, list, config);
} else if(itemTypeName == oatpp::data::mapping::type::__class::Float64::CLASS_NAME) {
writeListOfSimpleData<oatpp::data::mapping::type::Float64::ObjectType>(stream, list);
writeListOfSimpleData<oatpp::data::mapping::type::Float64::ObjectType>(stream, list, config);
} else if(itemTypeName == oatpp::data::mapping::type::__class::Boolean::CLASS_NAME) {
writeListOfSimpleData<oatpp::data::mapping::type::Boolean::ObjectType>(stream, list);
writeListOfSimpleData<oatpp::data::mapping::type::Boolean::ObjectType>(stream, list, config);
} else if(itemTypeName == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME) {
writeListOfObject(stream, list, itemType);
writeListOfObject(stream, list, itemType, config);
} else if(itemTypeName == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME) {
writeListOfList(stream, list, itemType);
writeListOfList(stream, list, itemType, config);
}
}
void Serializer::writeList(oatpp::data::stream::OutputStream* stream,
void* object,
Property* field){
Property* field,
const std::shared_ptr<Config>& config){
auto value = oatpp::data::mapping::type::static_wrapper_cast<AbstractList>(field->get(object));
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
if(!value){
stream->write("null", 4);
} else {
writeListCollection(stream, value.get(), field->type);
if(value) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
writeListCollection(stream, value.get(), field->type, config);
} else if(config->includeNullFields) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": null", 7);
}
}
void Serializer::writeObject(oatpp::data::stream::OutputStream* stream,
const Type* type,
Object* object){
Object* object,
const std::shared_ptr<Config>& config){
stream->writeChar('{');
bool firstField = true;
bool first = true;
auto fieldsMap = type->properties;
for (auto const& iterator : *fieldsMap) {
auto field = iterator.second;
if(firstField){
firstField = false;
} else {
stream->write(", ", 2);
auto abstractValue = field->get(object);
if(abstractValue) {
(first) ? first = false : stream->write(", ", 2);
} else if(config->includeNullFields) {
(first) ? first = false : stream->write(", ", 2);
}
auto type = field->type;
auto typeName = type->name;
if(typeName == oatpp::data::mapping::type::__class::String::CLASS_NAME){
writeString(stream, object, field);
writeString(stream, object, field, config);
} else if(typeName == oatpp::data::mapping::type::__class::Int32::CLASS_NAME) {
writeSimpleData<oatpp::data::mapping::type::Int32::ObjectType>(stream, object, field);
writeSimpleData<oatpp::data::mapping::type::Int32::ObjectType>(stream, object, field, config);
} else if(typeName == oatpp::data::mapping::type::__class::Int64::CLASS_NAME) {
writeSimpleData<oatpp::data::mapping::type::Int64::ObjectType>(stream, object, field);
writeSimpleData<oatpp::data::mapping::type::Int64::ObjectType>(stream, object, field, config);
} else if(typeName == oatpp::data::mapping::type::__class::Float32::CLASS_NAME) {
writeSimpleData<oatpp::data::mapping::type::Float32::ObjectType>(stream, object, field);
writeSimpleData<oatpp::data::mapping::type::Float32::ObjectType>(stream, object, field, config);
} else if(typeName == oatpp::data::mapping::type::__class::Float64::CLASS_NAME) {
writeSimpleData<oatpp::data::mapping::type::Float64::ObjectType>(stream, object, field);
writeSimpleData<oatpp::data::mapping::type::Float64::ObjectType>(stream, object, field, config);
} else if(typeName == oatpp::data::mapping::type::__class::Boolean::CLASS_NAME) {
writeSimpleData<oatpp::data::mapping::type::Boolean::ObjectType>(stream, object, field);
writeSimpleData<oatpp::data::mapping::type::Boolean::ObjectType>(stream, object, field, config);
} else if(typeName == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME) {
writeObject(stream, object, field);
writeObject(stream, object, field, config);
} else if(typeName == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME) {
writeList(stream, object, field);
writeList(stream, object, field, config);
}
}

@ -61,6 +61,8 @@ public:
return std::shared_ptr<Config>(new Config());
}
bool includeNullFields = true;
};
public:
@ -69,53 +71,56 @@ private:
static void writeString(oatpp::data::stream::OutputStream* stream,
void* object,
Property* field);
Property* field,
const std::shared_ptr<Config>& config);
template<class T>
static void writeSimpleData(oatpp::data::stream::OutputStream* stream,
void* object,
Property* field){
Property* field,
const std::shared_ptr<Config>& config){
auto value = oatpp::data::mapping::type::static_wrapper_cast<T>(field->get(object));
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
if(!value){
stream->write("null", 4);
} else {
if(value) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": ", 3);
stream->writeAsString(value.get()->getValue());
} else if(config->includeNullFields) {
stream->writeChar('\"');
stream->write(field->name);
stream->write("\": null", 7);
}
}
static void writeObject(oatpp::data::stream::OutputStream* stream,
void* object,
Property* field);
Property* field,
const std::shared_ptr<Config>& config);
static void writeListOfString(oatpp::data::stream::OutputStream* stream,
AbstractList* list);
AbstractList* list,
const std::shared_ptr<Config>& config);
template<class T>
static void writeListOfSimpleData(oatpp::data::stream::OutputStream* stream,
AbstractList* list){
AbstractList* list,
const std::shared_ptr<Config>& config){
stream->writeChar('[');
bool first = true;
auto curr = list->getFirstNode();
while(curr != nullptr){
auto value = oatpp::data::mapping::type::static_wrapper_cast<T>(curr->getData());
if(first){
first = false;
} else {
stream->write(", ", 2);
}
if(!value){
stream->write("null", 4);
} else {
if(value) {
(first) ? first = false : stream->write(", ", 2);
stream->writeAsString(value.get()->getValue());
} else if(config->includeNullFields) {
(first) ? first = false : stream->write(", ", 2);
stream->write("null", 4);
}
curr = curr->getNext();
}
stream->writeChar(']');
@ -124,33 +129,39 @@ private:
static void writeListOfObject(oatpp::data::stream::OutputStream* stream,
AbstractList* list,
const Type* const type);
const Type* const type,
const std::shared_ptr<Config>& config);
static void writeListOfList(oatpp::data::stream::OutputStream* stream,
AbstractList* list,
const Type* const type);
const Type* const type,
const std::shared_ptr<Config>& config);
static void writeListCollection(oatpp::data::stream::OutputStream* stream,
AbstractList* list,
const Type* const type);
const Type* const type,
const std::shared_ptr<Config>& config);
static void writeList(oatpp::data::stream::OutputStream* stream,
void* object,
Property* field);
Property* field,
const std::shared_ptr<Config>& config);
static void writeObject(oatpp::data::stream::OutputStream* stream,
const Type* const type,
Object* object);
Object* object,
const std::shared_ptr<Config>& config);
public:
static void serialize(const std::shared_ptr<oatpp::data::stream::OutputStream>& stream,
const oatpp::data::mapping::type::AbstractObjectWrapper& object){
const oatpp::data::mapping::type::AbstractObjectWrapper& object,
const std::shared_ptr<Config>& config){
auto type = object.valueType;
if(type->name == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME) {
writeObject(stream.get(), type, static_cast<Object*>(object.get()));
writeObject(stream.get(), type, static_cast<Object*>(object.get()), config);
} else if(type->name == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME) {
writeListCollection(stream.get(), static_cast<AbstractList*>(object.get()), type);
writeListCollection(stream.get(), static_cast<AbstractList*>(object.get()), type, config);
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::serialize()]: Unknown parameter type");
}