How to convert String to Set<Object>? - java

I have the following DTOs:
public class ConsumerDTO {
private String amount;
//...some other fields
}
public class ReceiverDTO {
private Set<PriceInfoDto> prices;
//...some other fields
}
public class PriceInfoDto {
private String amount;
//...some other fields
}
I want to convert ConsumerDTO to ReceiverDTO, p.s. map my data between differently structured objects. ConsumerDTO is my source class. ReceiverDTO is my target class. I tried this:
TypeMap<ConsumerDTO , ReceiverDTO> propertyMapper = this.mapper.createTypeMap(ConsumerDTO .class, ReceiverDTO.class);
propertyMapper.addMapping(ConsumerDTO ::getAmount, ReceiverDTO::getAmount);
But having trouble with getting amount from set in my target class. Is there a way to solve this? I also read some articles, but they show examples with simple types.

You can achieve the target object of ReceiverDTO from your source object ConsumerDTO as below:
Approach Here:
Here, I have added few more sample fields in the source as well as target class to show how to map other fields while creating a target object of type ReceiverDTO using getTargetTypeObject method.
public class Test {
public static void main(String[] args) {
//Source class objects
ConsumerDTO sourceObj = new ConsumerDTO();
sourceObj.setAmount("100");
//sample for Other fields in source object
sourceObj.setName("test");
sourceObj.setId(1000);
sourceObj.setFlag(true);
//sample for Other fields in source object
ReceiverDTO targetType = getTargetTypeObject(sourceObj);
System.out.println(targetType);
}
private static ReceiverDTO getTargetTypeObject(ConsumerDTO x) {
//Intermediate object creations
PriceInfoDto dto = new PriceInfoDto();
dto.setAmount(x.getAmount());
//Set other fields like this
dto.setName(x.getName());
dto.setId(x.getId());
dto.setFlag(x.isFlag());
//Set other fields like this
Set<PriceInfoDto> set = new HashSet<>();
set.add(dto);
//Target object
ReceiverDTO receiverDTO = new ReceiverDTO();
receiverDTO.setPrices(set);
return receiverDTO;
}
}
class ConsumerDTO {
private String amount;
private String name;
private int id;
private boolean flag;
//getters and setters
//toString
}
class ReceiverDTO {
private Set<PriceInfoDto> prices;
//getters and setters
//toString
}
class PriceInfoDto {
private String amount;
private String name;
private int id;
private boolean flag;
//getters and setters
//toString
}
Output:
ReceiverDTO{prices=[PriceInfoDto{amount='100', name='test', id=1000, flag=true}]}

Related

How to exclude object property

I using Orika mapper to map two beans. i would like to exclude billingSummary.billableItems property while mapping. I am trying below option but it is not working.
Any help?
public class Cart {
private String id;
private String name;
private BillingSummary billingSummary;
private String address;
//with getter and setter methods
}
public class BillingSummary {
private String billingItem;
private String billingItemId;
private BillableItems billableItems;
...
// with getter setter methods
}
//FilteredCart is same as Cart.
public class FilteredCart {
private String id;
private String name;
private BillingSummary billingSummary;
private String address;
//with getter and setter methods
}
#Component
public class CartMapper extends ConfigurableMapper {
#Override
public void configure(MapperFactory mapperFactory) {
mapperFactory.classMap(Cart.class,FilteredCart.class).exclude("billingSummary.billableItems").byDefault().register();
}
}
What you can do is adding another mapping to the mapperFactory in order to define how you want to map the BillingSummary to itself. In this way, when mapping from Cart to FilteredCart, you can configure to exclude to map the billableItems.
Therefore, your CartMapper will look like this:
#Component
public class CartMapper extends ConfigurableMapper {
#Override
public void configure(MapperFactory mapperFactory) {
mapperFactory.classMap(BillingSummary.class, BillingSummary.class).exclude("billableItems").byDefault().register();
mapperFactory.classMap(Cart.class,FilteredCart.class).byDefault().register();
}
}

Orika Mapping for unmodifiable List

I have got two immutable bean classes for which I am using Orika mapping to copy the values from one to other.
However, when I am trying to copy the unmodifiableList through Orika mapping, it fails by throwing below exception:
java.lang.UnsupportedOperationException
at ma.glasnost.orika.ExceptionUtility.newMappingException(ExceptionUtility.java:55)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:681)
at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:650)
at com.myproject.OrikaTest.testEmployeeMapping
I have provided the code below with which you can replicate the same issue:
EmployeeDto class:
public final class EmployeeDto {
private final int id;
private final String name;
private final List<String> previousGrades;
public EmployeeDto(int id, String name, List<String> previousGrades) {
this.id = id;//validations removed
this.name = name;//validations removed
//Commented unmodifiableList as it does not work
//this.previousGrades = Collections.unmodifiableList(previousGrades);
this.previousGrades = previousGrades;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public List<String> getPreviousGrades() {
//tried like this, even this does not work
return Collections.unmodifiableList(previousGrades);
}
}
Employee class:
public final class Employee {
//ditto AS EmployeeDto
}
OrikaTest class:
public class OrikaTest {
private static final MapperFactory mapperFactory =
new DefaultMapperFactory.Builder().build();
private static final MapperFacade mapperFacade =
mapperFactory.getMapperFacade();
#Test
public void testEmployeeMapping() {
List<String> employeeGrades = Arrays.asList("A", "B");
Employee employee = new Employee(1234, "John", employeeGrades);
EmployeeDto employeeDto = mapperFacade.map(employee, EmployeeDto.class);
//tests using assertEquals
Assert.assertEquals(employeeGrades, employeeDto.getPreviousGrades());
}
}
I could find a link here on this subject, but it was not that clear as alternatives were not explained properly.
So, can you help with an example or any workaround on how to copy the unmodifiableList through Orika mapping?
If the case is that Orika must be able to mutate the list components of the mapped objects then the following could be a work around:
Add a freeze method to your objects. When the objects are created they are in a mutable state. After freeze has been called it is no longer possible to mutate the objects.
It could be implemented like this:
public final class EmployeeDto {
private final int id;
private final String name;
private List<String> previousGrades;
public EmployeeDto(int id, String name, List<String> previousGrades) {
this.id = id;//validations removed
this.name = name;//validations removed
this.previousGrades = previousGrades;
}
public void freeze() {
previousGrades = Collections.unmodifiableList(previousGrades)
}
public List<String> getPreviousGrades() {
return previousGrades;
}
}

Jackson ignore serialization of top-level field if all its nested fields are null

I am using Jackson ObjectMapper to serialize a POJO. I have nested fields in the POJO. Eg: serializing class MyClass
public class MyClass {
private A a;
private int i;
//getters and setters
}
public class A {
private String s;
//getters and setters
}
I want that if String s is null, the entire property A does not get serialized. That is, if String s is null, I want the output to be:
{"myClass":{"i":10}}
But I am getting {"myClass":{"A":{},"i":10}} as the output instead.
I have set NON_EMPTY for serialization inclusion (mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)), but it doesn't solve the problem
AFAIK you cannot do this with standard annotations, but changing MyClass.getA() method in this way you should do the trick.
public A getA() {
if (a.getS() == null)
return null;
return a;
}
Generate hashCode() and equals() in the desired class.
public class A extends Serializable{
private String s;
// getters and setters
// hashCode() and equals()
}
Set an Include.CUSTOM in your parent class.
#JsonInclude(value = Include.CUSTOM, valueFilter = A.class)
public class MyClass extends Serializable {
private A a;
private int i;
//getters and setters
}
All empty objects will be excluded and the output will be: {"myClass":{"i":10}}
You need just to add #JsonInclude(JsonInclude.Include.NON_NULL)
#JsonInclude(JsonInclude.Include.NON_NULL)
public class MyClass implements Serializable {
private A a;
private int i;
//getters and setters
}
public class A implements Serializable{
private String s;
//getters and setters
}

Constructor method must contain all instance variables

Many times I'm faced with a class which constructor method must contain list of arguments that is identical with the list of class instance variables.
As you see in the example there is "SOME" code to make this hapend.
I'm wondering how can I make this process less painful?
Example:
public class VimeoUser extends Schema {
#Getter #Setter private String uri;
#Getter #Setter private String name;
#Getter #Setter private String link;
#Getter #Setter private String location;
#Getter #Setter private String bio;
#Getter #Setter private String createdTime;
#Getter #Setter private String account;
#Getter #Setter private Map<String,Integer> statistics = new HashMap<>();
#Getter #Setter private List<Website> websites = new ArrayList<>();
#Getter #Setter private List<Portrait> portraits = new ArrayList<>();
public VimeoUser(
String uri,
String name,
String link,
String location,
String bio,
String createdTime,
String account,
Map<String,Integer> statistics,
List<Website> websites,
List<Portrait> portraits){
this.uri = uri;
this.name = name;
this.link = link;
this.location = location;
this.bio = bio;
this.createdTime = createdTime;
this.account = account;
this.statistics = statistics;
this.websites = websites;
this.portraits = portraits;
}
}
It is possible to use a pattern named Builder. It is explained in this question
Basically it works as following:
Create an inner static class Builder
Create a private constructor that take as an argument an object of type Builder
In the Builder class add methods that set a single value and returns this (current reference to instance of the Builder class)
In the body of the constructor of your class use the values passed in the Builder to set each property
add a method build in the Builder that calls the private constructor of your class
Here is an example:
public class NutritionalFacts {
private int sodium;
private int fat;
private int carbo;
public class Builder {
private int sodium;
private int fat;
private int carbo;
public Builder(int s) {
this.sodium = s;
}
public Builder fat(int f) {
this.fat = f;
return this;
}
public Builder carbo(int c) {
this.carbo = c;
return this;
}
public NutritionalFacts build() {
return new NutritionalFacts(this);
}
}
private NutritionalFacts(Builder b) {
this.sodium = b.sodium;
this.fat = b.fat;
this.carbo = b.carbo;
}
}
and to use it do the following:
NutritionalFacts nutritionalFacts = new NutritionalFacts.Builder()
.fat(200).carbo(50).build();
Using this pattern instead of pojo with setter and getter is useful because it is possible to use it also to build immutable objects (objects with all final fields). An immutable object is useful if you need to share it on a multithreaded environment because it is not necessary to synchronize the access to it.
Additionally it is possible to add some controls in the build method to be sure that all fields are setted as expected.
I guess writing pojos for database modelling does not necessarily needs constructor other than default no-arg constructor. If anyway required in some situations, Getters and setters can be used.
Builder pattern
If you want create a object with more readable way, you can use a simple builder pattern. Lombok support this such as #Getter or #Setter. You just add #Builder annotation and everything should works fine.
#Getter
#Builder
public class SomeClass {
private final String valueOne;
private final String valueTwo;
}
And then you can create object in this way.
SomeClass someClass = SomeClass.builder()
.valueOne("one")
.valueTwo("two")
.build();
Fluent accessors method
Alternative way to create a class is using #Accessors annotation with fluent = true. Then you can create a empty object and set the value what you needed in simple way.
#Getter
#Setter
#Accessors(fluent = true)
public class SomeClass {
private String valueOne;
private String valueTwo;
}
Simple sample using this way.
SomeClass someClass = new SomeClass()
.valueOne("one")
.valueTwo("two");
I see you are already using Lombok. There is a #AllArgsConstructor class-level annotation that will generate the constructor for you. If you want the default constructor, too, use #NoArgsConstructor additionally.
More info on the constructor-generating annotations here.

How to get dot class of list of Objects?

I want to serialize an List of Object with SimpleFramework xml.
I succeed with ordinary class but not with List of object.
I don't find the good syntax for do it with a List of object.
List< Shop > shop = new Persister().read(List<Shop>.class, data);
List< Shop >.class doesn't work
Thanks
It's not possible to do this directly; use #ElementList instead.
Here's an example:
Shop class
#Default // Or customize as you need
public class Shop
{
private String name;
public Shop(String name)
{
this.name = name;
}
private Shop() { /* Required default ctor */ }
// ...
}
ListExample
This is just a wrapper around the list.
#Root(name = "example")
public static class ListExample
{
#ElementList(name = "Shops", inline = true)
private List<Shop> shops;
// ...
}
Usage
String input = ... // Or what source you have
Serializer ser = new Persister();
ListExample readExample = ser.read(ListExample.class, input);

Categories

Resources