Skip to content

Commit

Permalink
Jackson で直和型のオブジェクトマッピング定義を実装。
Browse files Browse the repository at this point in the history
  • Loading branch information
mikoto2000 committed Jul 3, 2023
1 parent e8d6bac commit 0140a32
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,81 @@
package dev.mikoto2000.springbootstudy.jackson.union.firststep;

import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import dev.mikoto2000.springbootstudy.jackson.union.firststep.model.Circle;
import dev.mikoto2000.springbootstudy.jackson.union.firststep.model.Rectangle;
import dev.mikoto2000.springbootstudy.jackson.union.firststep.model.Shape;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootApplication
public class FirststepApplication {

public static void main(String[] args) {
SpringApplication.run(FirststepApplication.class, args);
@Autowired
private ObjectMapper objectMapper;

public static void main(String[] args) throws JsonProcessingException {
ConfigurableApplicationContext context = SpringApplication.run(FirststepApplication.class, args);
FirststepApplication app = context.getBean(FirststepApplication.class);
app.process(args);
}

public void process(String... args) throws JsonProcessingException {

// Rectangle と Circle がごちゃ混ぜになったリストを走査し、
// それぞれを JSON 文字列として出力する。
List<Shape> shapes = Arrays.<Shape>asList(
new Rectangle(1, 2),
new Rectangle(3, 4),
new Circle(5),
new Circle(6)
);

for (Shape s : shapes) {
// 型の情報が type プロパティに格納されている JSON 文字列になった
log.info(this.objectMapper.writeValueAsString(s));
}


// Rectangle と Circle の JSON 文字列がごちゃ混ぜになったリストを走査し、
// Rectangle オブジェクトと Circle オブジェクトにマッピングしわける。
List<String> shapeJsonStrings = Arrays.<String>asList(
"""
{"type":"rectangle","width":1.0,"height":2.0}
""",
"""
{"type":"rectangle","width":3.0,"height":4.0}
""",
"""
{"type":"circle","r":5.0}
""",
"""
{"type":"circle","r":6.0}
"""
);

for (String shapeJsonString : shapeJsonStrings) {

// JSON 文字列から POJO へのマッピング
// type の値を基に、対応する型のオブジェクトへマッピングする
Shape shape = objectMapper.readValue(shapeJsonString, Shape.class);

if (shape instanceof Rectangle rectangle) {
// type の値が rectangle のものは、 Rectangle クラスにマッピングされている
log.info("Rectangle { width: {}, height: {} }", rectangle.getWidth(), rectangle.getHeight());
} else if (shape instanceof Circle circle) {
// type の値が circle のものは、 Circle クラスにマッピングされている
log.info("Circle { r: {} }", circle.getR());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.mikoto2000.springbootstudy.jackson.union.firststep.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
* JsonConfigure
*
* ObjectMapper を DI できるように Bean 定義するための Configuration
*/
@Configuration
public class JsonConfigure {
@Bean
public ObjectMapper mapper(){
return new ObjectMapper();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package dev.mikoto2000.springbootstudy.jackson.union.firststep.model;

import org.springframework.stereotype.Component;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
* Circle
*
* Shape の具象クラス。半径(r)をプロパティとして持つ。
*/
@Component
@Data
@EqualsAndHashCode(callSuper=true)
@AllArgsConstructor
@NoArgsConstructor
public class Circle extends Shape {
private double r;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dev.mikoto2000.springbootstudy.jackson.union.firststep.model;

import org.springframework.stereotype.Component;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
* Rectangle
*
* Shape の具象クラス。幅(width)と高さ(height)を持つ。
*/
@Component
@Data
@EqualsAndHashCode(callSuper=true)
@AllArgsConstructor
@NoArgsConstructor
public class Rectangle extends Shape {
private double width;
private double height;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.mikoto2000.springbootstudy.jackson.union.firststep.model;

import org.springframework.stereotype.Component;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import lombok.Data;

/**
* Shape
*
* 直和型(Rectangle | Circle) を定義。
*/
@Component
@JsonTypeInfo(
// 後ろで定義している JsonSubTypes の `name` を使って型を判定する
use = JsonTypeInfo.Id.NAME,
// 型情報をプロパティに格納する
include = JsonTypeInfo.As.PROPERTY,
// 格納するプロパティ名は `type`
property = "type"
)
@JsonSubTypes({
// "type": "circle" の場合、 Circle クラスにマッピングする
@JsonSubTypes.Type(value = Circle.class, name = "circle"),
// "type": "rectangle" の場合、 Rectangle クラスにマッピングする
@JsonSubTypes.Type(value = Rectangle.class, name = "rectangle")
})
@Data
public abstract class Shape {
}

0 comments on commit 0140a32

Please sign in to comment.