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:
parent
bb1a4db399
commit
fbf016107b
parser/json/mapping
@ -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");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user