#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include <iostream>
#include OATPP_CODEGEN_BEGIN(DTO)
class MyBaseDto : public oatpp::data::mapping::type::Object {
DTO_INIT(MyBaseDto, Object)
DTO_FIELD(String, myBaseDtoField);
};
class HeaderDto : public MyBaseDto /* Should also extend a class here */ {
DTO_INIT(HeaderDto, MyBaseDto)
DTO_FIELD(Int64, time);
};
class ResponseDto : public oatpp::data::mapping::type::Object {
DTO_INIT(ResponseDto, Object)
DTO_FIELD(HeaderDto::ObjectWrapper, header) = HeaderDto::createShared(); // Don't forger to initialize object
};
#include OATPP_CODEGEN_END(DTO)
void run() {
auto dto = ResponseDto::createShared();
dto->header->time = 0;
dto->header->myBaseDtoField = "Hello base class";
auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
auto json = objectMapper->writeToString(dto);
std::cout << json->c_str() << std::endl;
}
int main() {
oatpp::base::Environment::init();
run();
oatpp::base::Environment::destroy();
return 0;
}
Hello, i have a problem/question with your DTO component of oat++. I try to generate an packet with different types of objects but I can't assign inherited classes. I show you my problem with a little example
...
class Param : public oatpp::data::mapping::type::Object
{
DTO_INIT(Param , Object)
};
class RealParam : public Param
{
DTO_INIT(RealParam, Param)
DTO_FIELD(Int32, magic);
};
class Packet : public oatpp::data::mapping::type::Object
{
DTO_INIT(Packet, Object)
DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params)
= List<Param::ObjectWrapper>::createShared();
};
...
When I try to add an instance (ObjectWrapper) of type RealParam to the list of Packet, I only get an error message from the compiler that there is no known conversion from RealParam::ObjectWrapper to Param::ObjectWrapper. Is there a way to explicitly cast the object or am I still making a mistake somewhere?
Hello @DF-Dave ,
It is possible to cast ObjectWrapper
using oatpp::data::mapping::type::static_wrapper_cast
, and it will compile:
class Param : public oatpp::data::mapping::type::Object {
DTO_INIT(Param , Object);
};
class RealParam : public Param {
DTO_INIT(RealParam, Param)
DTO_FIELD(Int32, magic);
};
class Packet : public oatpp::data::mapping::type::Object {
DTO_INIT(Packet, Object)
DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params) = List<Param::ObjectWrapper>::createShared();
};
...
auto packet = Packet::createShared();
auto realParam = RealParam::createShared();
realParam->magic = 10;
Param::ObjectWrapper param = oatpp::data::mapping::type::static_wrapper_cast<Param>(realParam);
packet->params->pushBack(param);
But the output will miss the magic
int32 number:
{
"params": [
{}
]
}
DTO_FIELD(List<Param::ObjectWrapper>::ObjectWrapper, params)
in the Param inside <> brackets is the actual model of the object that should be serialized. Serializer won't know about other fields present in the child.
Not sure if I understand correctly...
The point is that the template parameter in the list should define the exact type of the object that you want to serialize.
You can just do like this:
class Param : public oatpp::data::mapping::type::Object {
DTO_INIT(Param , Object);
};
class RealParam : public Param {
DTO_INIT(RealParam, Param)
DTO_FIELD(Int32, magic);
};
class Packet : public oatpp::data::mapping::type::Object {
DTO_INIT(Packet, Object)
DTO_FIELD(List<RealParam::ObjectWrapper>::ObjectWrapper, params) = List<RealParam::ObjectWrapper>::createShared();
};
Then, your serializer will serialize all the fields taking into account the base class inheritance.
template<class T>
class Param : public oatpp::data::mapping::type::Object {
DTO_INIT(Param , Object);
DTO_FIELD(T, templateParam);
};
template<class T>
class Packet : public oatpp::data::mapping::type::Object {
DTO_INIT(Packet, Object)
typedef List<typename Param<T>::ObjectWrapper> ListOfParams;
typedef typename ListOfParams::ObjectWrapper ListOfParams_ObjectWrapper;
DTO_FIELD(ListOfParams_ObjectWrapper, params) = ListOfParams::createShared();
};
...
auto packet = Packet<oatpp::String>::createShared();
auto param = Param<oatpp::String>::createShared();
param->templateParam = "Hello";
packet->params->pushBack(param);
{
"params": [
{
"templateParam": "Hello"
}
]
}
@/all ,
Update :bell:
The new release with all the November changes is finally shipped 0.19.11.
ApiClient
. Introduce retries and RetryPolicy
.oatpp::network::virtual_::Interface
. Introduce ListenerLock
to acquire an interface for listening (analog to bind
on a port).oatpp::parser::json::mapping::Serializer
. Remove extra space char.oatpp::parser::json::mapping::Serializer
. Introduce Beautifier
and Beautifier config.v_buff_size
for buffer sizes, as an integer capable of storing a pointer.oatpp::data::stream::Context
to store aditional data about the stream.oatpp::network::server::SimpleTCPConnectionProvider
. Add feature to obtain peer IP and port available through the connection stream context.3.0.0
.Relevant documentation:
Cheers :tada:
Leonid
Hello @BossZou ,
example-async-api - is exactly what you need.
No matter what ConnectionProvider
is used - when you use AsyncHttpConnectionHandler, it will put accepted connection in the NON-BLOCKING
mode and then pass it to the processing coroutine.
Also, you should be careful not to put any blocking code inside the processing coroutine.
Regards,
Leonid
Hey @/all ,
Update :bell:
The new BIG stabilization release is now available 0.19.12
oatpp::data::buffer::Processor
and oatpp::data::buffer::ProcessingPipeline
for stream chunk-by-chunk processing.stop()
when using oatpp::network::server:: SimpleTCPConnectionProvider
. Now server can be properly stopped without additional workarounds.IODefinitions.hpp
to the root. Move v_io_size
, v_io_handle
and IOError
to the oatpp
namespace.InputStream
now extends ReadCallback
OutputStream
now extends WriteCallback
read
/write
methods now extended with additional parameter async::Action&
.suggestInputStreamAsyncAction
/ suggestOutputStreamAsyncAction
removed.oatpp::data::v_io_size
to oatpp::v_io_size
.oatpp::data::v_io_handle
to oatpp::v_io_handle
.oatpp::data::IOError
to oatpp::IOError
.writeSimple
instead of write
for ConsistentOutputStream
s - ChunkedBuffer
and BufferOutputStream
.stop()
. Now additional call to client::ConnectionProvider::getConnection()
method is not needed in order to unblock accept and stop the server.You are highly recommended to update your applications to the new Oat++ version.
Note: this is the last "pre" release - next is going to be version 1.0.0
. As it took longer than expected to deliver 0.19.12
, the 1.0.0
is shifted to the end of Jan - mid-Feb.
Cheers :tada:
Leonid