I have a long list of object mapping to do from classes auto generated by JAXB.
customer.setCustomerId(rentalCustomer.getCustomerid().getValue()));
customer.setCustomerName(rentalCustomer.getTradingname().getValue());
customer.setVatNumber(rentalSearchCustomer.getVatNumber().getValue());
....
....
Basically I need to make a null check for ALL fields:
getValue(RentalCustomerIDType idType){
if(idType != null){
return idType.getValue();
}
else {
return "";
}
}
Problem is there are too many of these and they all have different types: RentalCustomerIDType, TradingType, VatNumberType..etc
Is there an elegant way to this by creating a GENERIC method that makes null check and return proper values for ALL maybe using Functional Libraries for Java?
Perhaps use reflection on the class when it's generated and eliminate all nulls by assigning non-null values to the fields?
Check an replace null values in multiple variables java
They say (the guy who answered) that they strongly disagree with using reflection for this purpose... but... meh. I've done it and it works.
You could use a generic method to declare the getValueFromAllObjects
method and then use reflection to invoke the getValue
method
public static <T> String getValueFromAllObjects(T t) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
if(t != null){
return (String) t.getClass().getDeclaredMethod("getValue").invoke(t);
}
else {
return "";
}
}
Refer to https://stackoverflow.com/a/54883454/442256 for reflection alternatives. I've just inlined an example in your code above
From what I understand, you do not want to be changing existing auto-generated classes. What you can do is create a CustomerWrapper
class that wraps Customer
and inserts defaults when a null
is set to a field. This is the idea in code:
public class CustomerWrapper() {
private final Customer customer;
public CustomerWrapper(Customer customer) {
this.customer = customer;
}
public void setCustomerId(String id) {
this.customer.setCustomerId(id == null ? "" : id);
}
// Insert other methods here.
}
This does what you want. But there is a caveat. Each type must implement the same interface that provides the getValue()
method. Otherwise, you will probably need reflection to get the method as you suspected. But here is a solution for posterity.
setType(rentalSearchCustomer::getCustomerid,
customer::setCustomerId);
setType(rentalSearchCustomer::getTradingname,
customer::setCustomerName);
setType(rentalSearchCustomer::getVatNumber,
customer::setVatNumber);
System.out.println(customer);
public static <T extends GetValue> void setType(Supplier<T> sup,
Consumer<String> con) {
if (sup.get() == null) {
con.accept("");
} else {
con.accept(sup.get().getValue());
}
}
interface GetValue {
public String getValue();
}
I guess you want to use something like. here I have taken ResponseUserDto as my Pojo Class for null checks of it's properties.
private ResponseUserDto getValidNotNullPropertyObject(Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
Map < String, Object > result = new HashMap<>();
for (PropertyDescriptor property: src.getPropertyDescriptors()) {
if (src.getPropertyValue(property.getName()) == null) {
/* if(property.getPropertyType() == ?) {
//maybe do somethig here
}*/
result.put(property.getName(), ""); // this is start
} else {
result.put(property.getName(), src.getPropertyValue(property.getName()));
}
}
final ObjectMapper mapper = new ObjectMapper(); // Jackson's ObjectMapper
final ResponseUserDto finalResult = mapper.convertValue(result, ResponseUserDto.class);
return finalResult;
}
and to use this, you can call it like this
return this.getValidNotNullPropertyObject(responseUserDto);
maybe a case for Aspect Oriented Programming, if its use is an option:
using an Advice in AspectJ (see around advice
)
or (I have not checked this) Spring AOP How to change the return value by spring aop (closed, but has one answer)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.