[Java] How to substitute Model Mapper in Jackson

Introduction

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.

How to substitute ModelMapper with Jackson

Prerequisites

The following sources are written on the assumption that lombok is installed. https://projectlombok.org/

Overview

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.

  1. Convert Model1 to string (JSON)
  2. Convert the character string converted to JSON to Model2

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.

Mapping of models with Setter

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.

Full constructor model mapping

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);
    }
}

Finally

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.

reference

Recommended Posts

[Java] How to substitute Model Mapper in Jackson
How to learn JAVA in 7 days
How to use classes in Java?
How to name variables in Java
How to concatenate strings in java
How to implement Kalman filter in Java
How to embed Janus Graph in Java
How to get the date in java
How to assemble JSON directly in Jackson
How to get Class from Element in Java
How to hide null fields in response in Java
How to solve an Expression Problem in Java
How to write Java String # getBytes in Kotlin?
How to create a Java environment in just 3 seconds
[Java] How to omit the private constructor in Lombok
How to input / output IBM mainframe files in Java?
How to create a data URI (base64) in Java
How to generate / verify ID token in Java Memo
How to convert A to a and a to A using AND and OR in Java
How to convert a file to a byte array in Java
How to Git manage Java EE projects in Eclipse
Summary of how to implement default arguments in Java
How to put old Java (8 series) in macOS 10.15 Catalina
Notes on how to use regular expressions in Java
[Java] How to use Map
How to lower java version
[Java] How to use Map
How to uninstall Java 8 (Mac)
Java --How to make JTable
How to use java Optional
How to minimize Java images
How to write java comments
[Java] How to use Optional ②
[Java] How to use removeAll ()
[Java] How to use string.format
How to use Java Map
How to convert Java radix
[Java] How to implement multithreading
[Java] How to use Optional ①
How to initialize Java array
How to read your own YAML file (*****. Yml) in Java
How to use trained model of tensorflow2.0 with Kotlin / Java
How to use JSON data in WebSocket communication (Java, JavaScript)
How to pass an object to Mapper in MyBatis without arguments
Memo: [Java] How to check groupId etc. described in pom.xml
How to store a string from ArrayList to String in Java (Personal)
What happened in "Java 8 to Java 11" and how to build an environment
How to call and use API in Java (Spring Boot)
How to dynamically switch JDK when building Java in Gradle
How to develop and register a Sota app in Java
How to simulate uploading a post-object form to OSS in Java
How to deploy Java application to Alibaba Cloud EDAS in Eclipse
How to derive the last day of the month in Java
Differences in how to handle strings between Java and Perl
How to switch Java in the OpenJDK era on Mac
How to use Lombok in Spring
How to study Java Silver SE 8
How to use Java HttpClient (Get)
How to run JUnit in Eclipse
How to iterate infinitely in Ruby
Studying Java # 6 (How to write blocks)