I have a class SuccessResponse
that contains another custom class SuccessCustomerResponseBody
, both of these classes are a POJO model for some XML structure.
@JacksonXmlRootElement(localName = "response")
public class SuccessResponse {
private SuccessCustomerResponseBody ok;
public SuccessCustomerResponseBody getOk() {
return ok;
}
public void setOk(SuccessCustomerResponseBody ok) {
this.ok = ok;
}
}
and SuccessCustomerResponseBody
@Getter
@Setter
public class SuccessCustomerResponseBody {
@JacksonXmlElementWrapper(localName = "customers")
private List<Customer> customers;
private String requestId;
@JacksonXmlProperty(localName = "customer")
public List<Customer> getCustomers() {
return customers;
}
}
This model is used to fetch data from a database, and return as an XML response in service controller GetCustomer
. It looks okay except when it's required to add another controller to return for example customer packages. So, the easiest way, to create two more classes like SuccessPackageResponse
and SuccessPackageResponseBody
, rename SuccessResponse
to SuccessCustomerResponse
and that's it. Well done
@JacksonXmlRootElement(localName = "response")
public class SuccessPackageResponse {
private SuccessPackageResponseBody ok;
public SuccessPackageResponseBody getOk() {
return ok;
}
public void setOk(SuccessPackageResponseBody ok) {
this.ok = ok;
}
}
SuccessPackageResponseBody
@Getter
@Setter
public class SuccessPackageResponseBody {
@JacksonXmlElementWrapper(localName = "packages")
private List<Package> packages;
private String requestId;
@JacksonXmlProperty(localName = "package")
public List<Package> getPackages() {
return packages;
}
}
The main problem is that this approach produces a lot of code. So, I tried to re-use SuccessResponse
by implementing this class as generic one.
@JacksonXmlRootElement(localName = "response")
public class SuccessResponse<T> {
private T ok;
public T getOk() {
return ok;
}
public void setOk(T ok) {
this.ok = ok;
}
}
Looks better, right? We can use it like:
SuccessResponse<SuccessCustomerResponseBody> successCustomerResponse = objectMapper.convertValue(node.getMap().get("response"), SuccessResponse.class);
I thought that this is my solution, but I found that ObjectMapper
configs are not applied in such approach and I don't understand why.
objectMapper.configOverride(String.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
To finalise, I have two questions:
- Any idea how to re-use
SuccessResponse
in case when custom type (SuccessCustomerResponseBody
) can be dynamically changed. - Why
ObjectMapper
config isn't applied in solution with generic?