Open l16h7n1n6s opened 1 year ago
Hi, @l16h7n1n6s
ActiveJ Serializer does not support generic T
types as it requires concrete types to be resolved in order to build a serializer for a type. You would also need to know in advance which types could be serialized as a T
.
The simplest solution to your issue would be to replace a generic T
with an Object class. So, instead of List<T>
you would have a List<Object>
.
You would still need to pass all possible types that could be stored in a class. You would need to use @SerializeClass
annotation for this (enumerate possible subclasses using a subclasses
attribute).
Your response class could look like this (assuming that List may contain Integers and Strings):
public class Response {
private List<Object> data;
public Response(@Deserialize("data") List<Object> data) {
this.data = data;
}
@Serialize
public List<@SerializeClass(subclasses = {String.class, Integer.class}) Object> getData() {
return data;
}
public void setData(List<Object> data) {
this.data = data;
}
}
However, now you are allowed to pass a list of mixed elements, for example List.of(“test”, 1, “example”);
. Another disadvantage is that for every element of serialized list an additional byte is used to encode a type of the element.
Another, a bit more complicated solution, is to serialize not a List<T>
, but some container interface, like ListHolder<T>
. You would need to create some additional classes, but, overall, it would solve the above-mentioned problems.
Here is how your classes could look like:
@SuppressWarnings("unchecked")
public class Response<T> {
private ListHolder<?> listHolder;
public Response(@Deserialize("listHolder") ListHolder<?> listHolder) {
this.listHolder = listHolder;
}
@Serialize
public ListHolder<?> getListHolder() {
return listHolder;
}
public List<T> getData() {
return (List<T>) listHolder.getList();
}
public void setListHolder(ListHolder<T> listHolder) {
this.listHolder = listHolder;
}
}
@SerializeClass(subclasses = {IntegerListHolder.class, StringListHolder.class})
public interface ListHolder<T> {
List<T> getList();
}
public class IntegerListHolder implements ListHolder<Integer> {
private final List<Integer> list;
public IntegerListHolder(@Deserialize("list") List<Integer> list) {
this.list = list;
}
@Override
@Serialize
public List<Integer> getList() {
return list;
}
}
public class StringListHolder implements ListHolder<String> {
private final List<String> list;
public StringListHolder(@Deserialize("list") List<String> list) {
this.list = list;
}
@Override
@Serialize
public List<String> getList() {
return list;
}
}
@eduard-vasinskyi thanks for you wonderful message your are my Hero!!!!!!
i am trying to create an RPC server/client but i want the response to be generic but i failed this is an example from error that i get in server when trying to listen on port. Can you provide an example with solution here if possible?
thanks in advance
Here is what i want to achieve this is my response class:
here is what i do
and i think the problem is here in this line
.withMessageTypes(Request.class,fluentType.getClass())
Any help how to fix this issue?An alternative way that i thinking is to send bytes as response and then manually deserialize it when it will bereceived. will this approach add extra delay overhead or its ok to do it?