This time it's a way to make Jackson a substitute for Model Mapper. This is useful in special situations where you can use Jackson but not ModelMapper.
Normally, I don't think I'll come across a situation where this is necessary, but at the site where I am now, Jackson can be used, but ModelMapper cannot be used.
I came up with this method when I was wondering if it would be possible to map as much as ModelMapper with a limited library.
The following sources are written on the assumption that lombok is installed. https://projectlombok.org/
For ease of use, define a wrapper class for ObjectMapper. Error handling is omitted, so add it as appropriate.
JacksonModelMapper.java
public class JacksonModelMapper {
private final ObjectMapper objectMapper = new ObjectMapper();
public <T1, T2> map(T1 obj1, Class<T2> clazz) {
try {
String str = objectMapper.writeValueAsString(obj1);
return objectMapper.readValue(str, clazz);
} catch (IOExcepetion e) {
// ignore
return null;
}
}
}
The mechanism of model mapping is as follows.
Since the model is converted to JSON once and converted to another model, it is processing redundant. It's not a performance measure, but it's best to avoid it if speed is critical.
If Setter exists in the conversion destination model, it is as follows.
Model.java
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Model {
private Integer id;
private String name;
private String organizationCode;
private String organizationName;
}
Model2.java
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Model2 {
private Integer id;
private String name;
private String organizationCode;
private String postCode;
}
Main.java
public class Main {
public void execute() {
Model1 model1 = new Model();
model1.setId(1);
model1.setName("hrk-okd");
model1.setOrganizationCode("000001");
model1.setOrganizationName("ritsuan");
JacksonModelMapper mapper = new JacksonModelMapper();
Model2 model2 = mapper.map(model1, Model2.class);
}
}
I think it is implemented in a simple way.
@JsonIgnoreProperties (ignoreUnknown = true)
is necessary so that an error does not occur even if the property does not exist at the mapping destination.
In the above case, when mapping an organizationName that does not exist in Model2, you can control whether to make an error or continue processing.
If the conversion destination model is Immutable with only a complete constructor, you need to devise something.
--Added @JsonCreator
to the constructor
--Added @JsonProperty ("hogehoge ")
to the constructor argument
I referred to the following. https://www.366service.com/jp/qa/edd9ec25c79a01ec00724754bb257d11
Model.java
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Model {
private Integer id;
private String name;
private String organizationCode;
private String organizationName;
}
Model2.java
@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
public class Model2 {
private final Integer id;
private final String name;
private final String organizationCode;
private final String postCode;
@JsonCreator
public Model2(@JsonProperty("id") final Integer id,
@JsonProperty("name") final String name,
@JsonProperty("organizationCode") final String organizationCode,
@JsonProperty("postCode") final String postCode) {
this.id = id;
this.name = name;
this.organizationCode= organizationCode;
this.postCode= postCode;
}
}
Main.java
public class Main {
public void execute() {
Model1 model1 = new Model();
model1.setId(1);
model1.setName("hrk-okd");
model1.setOrganizationCode("000001");
model1.setOrganizationName("ritsuan");
JacksonModelMapper mapper = new JacksonModelMapper();
Model2 model2 = mapper.map(model1, Model2.class);
}
}
In many cases, the mapping library only supports the properties where getters and setters exist. However, this method can also be used for fully constructor models. The disadvantage is that you have to add extra annotations, but if there is no other way, you can try it.
ModelMapper http://modelmapper.org/
Jackson https://github.com/FasterXML/jackson-docs
Recommended Posts