Today in the packaging of third-party applications open interface, write a lot of return value class, many of these classes are similar in structure only individual field names are not the same. In order to separate the fields to copy a change is not to win, and the name is the most headache. Like the following two.
Is it similar? So they were merged using generics.
This way they can be defined via UserResponse<SimpleUser>
and UserResponse<UserDetail>
, simplifying the code quite a bit. But it didn’t take long for another class to come along.
This structure is actually pretty much the same, if you take UserResponse<T>
and transform it further into.
It seems that OjbectResponse<String>
is equivalent to QrCodeResponse
. However, it is not possible to simply do this, as careful students will notice that the names of their properties are different, one is qrcode
and the other is userlist
. It would be nice if they had different names! I seem to have a solution.
If it’s a type conversion
If it’s a Bean type conversion, using Mapstruct solves the problem and we end up defining the property name as data
.
This is solved by writing two conversion interfaces with the two annotated maps above. For Mapstruct you can see my related article explaining it.
If it’s deserialization
Jackson provides an alias annotation @JsonAlias
that allows field attribute names to accept more aliases. Like this.
Then the following json can be mapped to OjbectResponse<String>
.
This will map to OjbectResponse<List<UserDetail>>
.
By this point you may have questions: How does Jackson handle generics?
How to get the Class type of a generic type
You can’t get the Class
type of a generic type by direct means, but we can get the abstract definition of a generic type java.lang.reflect.ParameterizedType
, and it’s not very convenient to use ParameterizedType
directly. So in Jackson you can handle generics with TypeReference<T>
. If we need to deserialize OjbectResponse<String>
we can do so.
Spring actually provides a similar tool class org.springframework.core.ParameterizedTypeReference<T>
, especially if you are using RestTemplate
to request third-party generic processing tools.