DTOs
Fulib makes it easy to generate DTOs (Data Transfer Objects) from existing model classes without a lot of duplication.
We recommend putting all DTOs into a package and GenDtos class that are separate from your model.
Here’s an example:
src/gen/java/org/example/dtos/model/GenModel:
public class GenModel implements ClassModelDecorator
{
public class User
{
String id;
String name;
@Link("user")
Address address;
}
public class Address
{
String id;
String city;
String street;
@Link("address")
User user;
}
@Override
public void decorate(ClassModelManager m)
{
m.haveNestedClasses(GenModel.class);
}
}
src/gen/java/org/example/dtos/dto/GenDtos:
public class GenDtos implements ClassModelDecorator
{
@DTO(model = GenModel.User.class, omit = { "id" })
class UserDto
{}
@DTO(model = GenModel.Address.class, pick = { "city", "street" })
class AddressDto
{}
@Override
public void decorate(ClassModelManager m)
{
// This omits PropertyChangeListeners etc. from the generated code
m.getClassModel().setDefaultPropertyStyle(Type.POJO);
m.haveNestedClasses(GenDtos.class);
}
}
The example shows the basic usage of the @DTO annotation.
modelsets the model class we want to copy fields from.omitis optional and specifies which fields should not be copied to the DTO class.pickis optional and specifies which fields should be copied to the DTO class. Ifpickis provided, all other fields will be ignored.
Let’s take a look at the generated code:
src/main/java/org/example/dtos/dto/UserDto.java
```java
public class UserDto
{
public static final String PROPERTY_NAME = "name";
public static final String PROPERTY_ADDRESS = "address";
private String name;
private String address;
public String getName()
{
return this.name;
}
public UserDto setName(String value)
{
this.name = value;
return this;
}
public String getAddress()
{
return this.address;
}
public UserDto setAddress(String value)
{
this.address = value;
return this;
}
@Override
public String toString()
{
final StringBuilder result = new StringBuilder();
result.append(' ').append(this.getName());
result.append(' ').append(this.getAddress());
return result.substring(1);
}
}
```
src/main/java/org/example/dtos/dto/AddressDto.java
```java
public class AddressDto
{
public static final String PROPERTY_CITY = "city";
public static final String PROPERTY_STREET = "street";
private String city;
private String street;
public String getCity()
{
return this.city;
}
public AddressDto setCity(String value)
{
this.city = value;
return this;
}
public String getStreet()
{
return this.street;
}
public AddressDto setStreet(String value)
{
this.street = value;
return this;
}
@Override
public String toString()
{
final StringBuilder result = new StringBuilder();
result.append(' ').append(this.getCity());
result.append(' ').append(this.getStreet());
return result.substring(1);
}
}
```
In the UserDto class, we can see that all attributes from User were copied over except for id, because it was specified in omit.
The address association in User was converted to a String field, which can hold the Address ID in our DTO.
The AddressDto class contains only the city and street attributes, thanks to the pick array.
For completeness, here is the generated code for the User and Address model classes.
Note how these use the default Bean property style, which generates PropertyChange support.