Spring Boot REST APIでは、JavaオブジェクトとJSONの相互変換をJacksonライブラリが自動的に処理します。本記事では、Jacksonアノテーションによるフィールド名変更・除外、日付フォーマットの設定、ObjectMapperのカスタマイズ、そしてカスタムシリアライザ・デシリアライザの実装について、実践的なコード例とともに解説します。
実行環境と前提条件#
本記事の内容を実践するにあたり、以下の環境を前提としています。
| 項目 |
バージョン・要件 |
| Java |
17以上 |
| Spring Boot |
3.4.x |
| Jackson |
2.17.x(Spring Boot 3.4に同梱) |
| ビルドツール |
Maven または Gradle |
| IDE |
VS Code(Extension Pack for Javaインストール済み) |
また、本記事はSpring Boot REST APIのリクエスト・レスポンス処理の続編として、基本的なSpring Boot REST APIの知識があることを前提としています。
期待される学習成果#
本記事を読み終えると、以下のことができるようになります。
- Jacksonアノテーションを使ってJSONのフィールド名変更や除外ができる
- 日付・時刻型のフォーマットをカスタマイズできる
ObjectMapperをカスタマイズしてアプリケーション全体のJSON処理を統一できる
- カスタムシリアライザ・デシリアライザで複雑な変換ロジックを実装できる
JacksonによるJSON変換の仕組み#
Spring Bootでは、spring-boot-starter-webを追加すると、自動的にJacksonが含まれます。@RestControllerのメソッドが返すオブジェクトは、JacksonのObjectMapperによってJSONにシリアライズされ、リクエストボディのJSONはJavaオブジェクトにデシリアライズされます。
flowchart LR
subgraph シリアライズ
A[Javaオブジェクト] -->|ObjectMapper| B[JSON文字列]
end
subgraph デシリアライズ
C[JSON文字列] -->|ObjectMapper| D[Javaオブジェクト]
end基本的な変換の流れ#
以下は、Spring BootでのJSON変換の基本的な流れを示すコード例です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.example.demoapi.dto;
public class UserResponse {
private Long id;
private String name;
private String email;
// コンストラクタ
public UserResponse(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// Getter(Jacksonはgetterを使ってシリアライズする)
public Long getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
}
|
このクラスをレスポンスとして返すと、以下のJSONが生成されます。
1
2
3
4
5
|
{
"id": 1,
"name": "山田太郎",
"email": "yamada@example.com"
}
|
Jacksonアノテーションによるフィールド名変更・除外#
Jacksonには、JSON変換をカスタマイズするための豊富なアノテーションが用意されています。以下では、よく使用されるアノテーションを解説します。
@JsonPropertyによるフィールド名の変更#
@JsonPropertyアノテーションを使用すると、JSONのプロパティ名をJavaのフィールド名と異なる名前に変更できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.example.demoapi.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
public class UserResponse {
private Long id;
@JsonProperty("user_name")
private String name;
@JsonProperty("email_address")
private String email;
public UserResponse(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public Long getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
}
|
このクラスは以下のJSONを生成します。
1
2
3
4
5
|
{
"id": 1,
"user_name": "山田太郎",
"email_address": "yamada@example.com"
}
|
@JsonIgnoreによるフィールドの除外#
@JsonIgnoreアノテーションを使用すると、特定のフィールドをJSON変換から除外できます。パスワードやセンシティブな情報をレスポンスに含めたくない場合に便利です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package com.example.demoapi.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class UserDetailResponse {
private Long id;
private String name;
private String email;
@JsonIgnore
private String password;
@JsonIgnore
private String internalNote;
public UserDetailResponse(Long id, String name, String email,
String password, String internalNote) {
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.internalNote = internalNote;
}
// Getter
public Long getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
public String getPassword() { return password; }
public String getInternalNote() { return internalNote; }
}
|
出力されるJSONにはpasswordとinternalNoteは含まれません。
1
2
3
4
5
|
{
"id": 1,
"name": "山田太郎",
"email": "yamada@example.com"
}
|
@JsonIgnorePropertiesによる複数フィールドの除外#
クラスレベルで複数のフィールドを一括で除外したい場合は、@JsonIgnorePropertiesを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package com.example.demoapi.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties({"password", "internalNote", "createdBy"})
public class UserDetailResponse {
private Long id;
private String name;
private String email;
private String password;
private String internalNote;
private String createdBy;
// コンストラクタとGetter(省略)
}
|
また、デシリアライズ時に未知のプロパティを無視したい場合は以下のように設定します。
1
2
3
4
5
6
7
|
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserCreateRequest {
private String name;
private String email;
// JSONに余分なフィールドがあってもエラーにならない
}
|
@JsonIncludeによるnull値・空値の除外#
@JsonIncludeアノテーションを使用すると、null値や空の値を持つフィールドをJSONから除外できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.example.demoapi.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserResponse {
private Long id;
private String name;
private String email;
private String phoneNumber; // nullの場合はJSONに含まれない
public UserResponse(Long id, String name, String email, String phoneNumber) {
this.id = id;
this.name = name;
this.email = email;
this.phoneNumber = phoneNumber;
}
// Getter
public Long getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
public String getPhoneNumber() { return phoneNumber; }
}
|
phoneNumberがnullの場合、出力されるJSONは以下のようになります。
1
2
3
4
5
|
{
"id": 1,
"name": "山田太郎",
"email": "yamada@example.com"
}
|
@JsonIncludeで使用できる主なオプションは以下の通りです。
| オプション |
説明 |
Include.ALWAYS |
常にすべてのフィールドを含める(デフォルト) |
Include.NON_NULL |
nullでないフィールドのみ含める |
Include.NON_EMPTY |
null、空文字列、空コレクションを除外 |
Include.NON_DEFAULT |
デフォルト値と異なる場合のみ含める |
日付フォーマットの設定#
REST APIでは日付・時刻のフォーマットが重要です。Jacksonでは@JsonFormatアノテーションを使用して、日付・時刻のシリアライズ・デシリアライズ形式を指定できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package com.example.demoapi.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class EventResponse {
private Long id;
private String title;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate eventDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdAt;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "Asia/Tokyo")
private LocalDateTime updatedAt;
public EventResponse(Long id, String title, LocalDate eventDate,
LocalDateTime createdAt, LocalDateTime updatedAt) {
this.id = id;
this.title = title;
this.eventDate = eventDate;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
// Getter
public Long getId() { return id; }
public String getTitle() { return title; }
public LocalDate getEventDate() { return eventDate; }
public LocalDateTime getCreatedAt() { return createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
}
|
出力されるJSONは以下のようになります。
1
2
3
4
5
6
7
|
{
"id": 1,
"title": "技術カンファレンス",
"eventDate": "2026-03-15",
"createdAt": "2026-01-04 10:30:00",
"updatedAt": "2026-01-04T10:30:00.000+09:00"
}
|
Java 8 Date/Time APIのサポート#
Spring Boot 3.xでは、jackson-datatype-jsr310モジュールが自動的に含まれているため、LocalDate、LocalDateTime、ZonedDateTimeなどのJava 8 Date/Time APIがそのままサポートされます。
ただし、デフォルトではISO-8601形式でシリアライズされるため、独自のフォーマットが必要な場合は@JsonFormatを使用するか、後述するObjectMapperのカスタマイズを行います。
application.propertiesによるグローバル設定#
アプリケーション全体で共通の日付フォーマットを設定したい場合は、application.properties(またはapplication.yml)で設定できます。
1
2
3
|
# application.properties
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=Asia/Tokyo
|
1
2
3
4
5
|
# application.yml
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: Asia/Tokyo
|
ObjectMapperのカスタマイズ#
ObjectMapperはJacksonの中心的なクラスで、JSON変換のすべての設定を管理します。Spring Bootでは、@BeanとしてObjectMapperを定義することで、アプリケーション全体のJSON処理をカスタマイズできます。
ObjectMapperのBean定義#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.example.demoapi.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// Java 8 Date/Time APIのサポート
mapper.registerModule(new JavaTimeModule());
// 日付をタイムスタンプではなく文字列で出力
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 未知のプロパティを無視
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// null値をJSONに含めない
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// スネークケースに変換(user_name形式)
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
// 空のオブジェクトでエラーにしない
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
return mapper;
}
}
|
Jackson2ObjectMapperBuilderによるカスタマイズ#
Spring Bootでは、Jackson2ObjectMapperBuilderを使用してより簡潔にObjectMapperをカスタマイズすることもできます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package com.example.demoapi.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.text.SimpleDateFormat;
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
return new Jackson2ObjectMapperBuilder()
.dateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
.serializationInclusion(JsonInclude.Include.NON_NULL)
.propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
.failOnUnknownProperties(false)
.featuresToDisable(
com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
);
}
}
|
主要な設定オプション一覧#
以下の表は、ObjectMapperでよく使用される設定オプションをまとめたものです。
| 設定 |
説明 |
デフォルト |
WRITE_DATES_AS_TIMESTAMPS |
日付をタイムスタンプで出力 |
true |
FAIL_ON_UNKNOWN_PROPERTIES |
未知のプロパティでエラー |
true |
FAIL_ON_EMPTY_BEANS |
空のBeanでエラー |
true |
INDENT_OUTPUT |
JSONを整形して出力 |
false |
WRITE_ENUMS_USING_TO_STRING |
EnumをtoString()で出力 |
false |
カスタムシリアライザの実装#
複雑な変換ロジックが必要な場合は、カスタムシリアライザを実装します。例えば、金額を通貨記号付きでフォーマットしたり、特定の条件でフィールドの値を変換したりする場合に有用です。
基本的なカスタムシリアライザ#
以下は、金額を円表記でフォーマットするカスタムシリアライザの例です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package com.example.demoapi.serializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Locale;
public class JapaneseCurrencySerializer extends JsonSerializer<BigDecimal> {
private static final NumberFormat CURRENCY_FORMAT =
NumberFormat.getCurrencyInstance(Locale.JAPAN);
@Override
public void serialize(BigDecimal value, JsonGenerator gen,
SerializerProvider serializers) throws IOException {
if (value != null) {
gen.writeString(CURRENCY_FORMAT.format(value));
} else {
gen.writeNull();
}
}
}
|
カスタムシリアライザの適用#
カスタムシリアライザは@JsonSerializeアノテーションを使用してフィールドに適用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package com.example.demoapi.dto;
import com.example.demoapi.serializer.JapaneseCurrencySerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.math.BigDecimal;
public class ProductResponse {
private Long id;
private String name;
@JsonSerialize(using = JapaneseCurrencySerializer.class)
private BigDecimal price;
@JsonSerialize(using = JapaneseCurrencySerializer.class)
private BigDecimal taxIncludedPrice;
public ProductResponse(Long id, String name, BigDecimal price,
BigDecimal taxIncludedPrice) {
this.id = id;
this.name = name;
this.price = price;
this.taxIncludedPrice = taxIncludedPrice;
}
// Getter
public Long getId() { return id; }
public String getName() { return name; }
public BigDecimal getPrice() { return price; }
public BigDecimal getTaxIncludedPrice() { return taxIncludedPrice; }
}
|
出力されるJSONは以下のようになります。
1
2
3
4
5
6
|
{
"id": 1,
"name": "ノートパソコン",
"price": "¥98,000",
"taxIncludedPrice": "¥107,800"
}
|
複雑なオブジェクトのカスタムシリアライザ#
複雑なオブジェクトを特定の形式でシリアライズする例を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package com.example.demoapi.serializer;
import com.example.demoapi.entity.Address;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class AddressSerializer extends JsonSerializer<Address> {
@Override
public void serialize(Address address, JsonGenerator gen,
SerializerProvider serializers) throws IOException {
if (address != null) {
// 住所を一行の文字列として出力
String fullAddress = String.format("〒%s %s%s%s",
address.getPostalCode(),
address.getPrefecture(),
address.getCity(),
address.getStreet());
gen.writeString(fullAddress);
} else {
gen.writeNull();
}
}
}
|
カスタムデシリアライザの実装#
リクエストで受け取るJSONを特定の形式からJavaオブジェクトに変換する場合は、カスタムデシリアライザを実装します。
基本的なカスタムデシリアライザ#
以下は、様々な形式の日付文字列をLocalDateに変換するデシリアライザの例です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package com.example.demoapi.serializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;
public class FlexibleLocalDateDeserializer extends JsonDeserializer<LocalDate> {
private static final List<DateTimeFormatter> FORMATTERS = Arrays.asList(
DateTimeFormatter.ofPattern("yyyy-MM-dd"),
DateTimeFormatter.ofPattern("yyyy/MM/dd"),
DateTimeFormatter.ofPattern("yyyyMMdd"),
DateTimeFormatter.ofPattern("yyyy年MM月dd日")
);
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
String dateString = p.getValueAsString();
if (dateString == null || dateString.isEmpty()) {
return null;
}
for (DateTimeFormatter formatter : FORMATTERS) {
try {
return LocalDate.parse(dateString, formatter);
} catch (DateTimeParseException e) {
// 次のフォーマットを試す
}
}
throw new IOException("サポートされていない日付形式です: " + dateString);
}
}
|
カスタムデシリアライザの適用#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package com.example.demoapi.dto;
import com.example.demoapi.serializer.FlexibleLocalDateDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.time.LocalDate;
public class EventCreateRequest {
private String title;
@JsonDeserialize(using = FlexibleLocalDateDeserializer.class)
private LocalDate eventDate;
// デフォルトコンストラクタ(Jacksonのデシリアライズに必要)
public EventCreateRequest() {}
// Getter/Setter
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public LocalDate getEventDate() { return eventDate; }
public void setEventDate(LocalDate eventDate) { this.eventDate = eventDate; }
}
|
これにより、以下のいずれの形式でも日付を受け付けられます。
1
2
3
4
|
{ "title": "会議", "eventDate": "2026-03-15" }
{ "title": "会議", "eventDate": "2026/03/15" }
{ "title": "会議", "eventDate": "20260315" }
{ "title": "会議", "eventDate": "2026年03月15日" }
|
モジュールによるシリアライザ・デシリアライザの一括登録#
カスタムシリアライザ・デシリアライザをモジュールとして登録すると、アノテーションなしで型ごとに自動適用できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package com.example.demoapi.config;
import com.example.demoapi.serializer.JapaneseCurrencySerializer;
import com.example.demoapi.serializer.FlexibleLocalDateDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.math.BigDecimal;
import java.time.LocalDate;
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
// BigDecimal型には常にJapaneseCurrencySerializerを使用
module.addSerializer(BigDecimal.class, new JapaneseCurrencySerializer());
// LocalDate型のデシリアライズにはFlexibleLocalDateDeserializerを使用
module.addDeserializer(LocalDate.class, new FlexibleLocalDateDeserializer());
mapper.registerModule(module);
return mapper;
}
}
|
よくあるトラブルと解決策#
無限ループの回避#
エンティティ間の双方向関連では、シリアライズ時に無限ループが発生する可能性があります。@JsonManagedReferenceと@JsonBackReferenceを使用して回避します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package com.example.demoapi.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;
import java.util.List;
public class Department {
private Long id;
private String name;
@JsonManagedReference
private List<Employee> employees;
// Getter/Setter
}
public class Employee {
private Long id;
private String name;
@JsonBackReference
private Department department;
// Getter/Setter
}
|
Enumのカスタマイズ#
Enumをカスタム値でシリアライズする場合は、@JsonValueと@JsonCreatorを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package com.example.demoapi.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
public enum OrderStatus {
PENDING("pending", "保留中"),
PROCESSING("processing", "処理中"),
COMPLETED("completed", "完了"),
CANCELLED("cancelled", "キャンセル");
private final String code;
private final String displayName;
OrderStatus(String code, String displayName) {
this.code = code;
this.displayName = displayName;
}
@JsonValue
public String getCode() {
return code;
}
@JsonCreator
public static OrderStatus fromCode(String code) {
for (OrderStatus status : values()) {
if (status.code.equals(code)) {
return status;
}
}
throw new IllegalArgumentException("Unknown status code: " + code);
}
public String getDisplayName() {
return displayName;
}
}
|
この設定により、JSONでは"pending"のような文字列として出力され、同様の文字列からEnumに変換できます。
アノテーション一覧#
本記事で紹介したJacksonアノテーションをまとめます。
| アノテーション |
用途 |
@JsonProperty |
JSONプロパティ名を指定 |
@JsonIgnore |
フィールドをシリアライズ・デシリアライズから除外 |
@JsonIgnoreProperties |
クラスレベルで複数フィールドを除外 |
@JsonInclude |
null値や空値の出力制御 |
@JsonFormat |
日付・時刻のフォーマット指定 |
@JsonSerialize |
カスタムシリアライザの指定 |
@JsonDeserialize |
カスタムデシリアライザの指定 |
@JsonValue |
シリアライズ時に使用する値を指定 |
@JsonCreator |
デシリアライズ時のファクトリメソッドを指定 |
@JsonManagedReference |
双方向関連の親側 |
@JsonBackReference |
双方向関連の子側 |
まとめ#
本記事では、Spring Boot REST APIにおけるJacksonによるJSON処理のカスタマイズについて解説しました。
- Jacksonアノテーションを使用することで、フィールド名の変更、除外、null値の制御が簡単にできます
- 日付フォーマットは
@JsonFormatアノテーションまたはObjectMapperの設定でカスタマイズできます
- ObjectMapperのBean定義により、アプリケーション全体のJSON処理を統一できます
- カスタムシリアライザ・デシリアライザを実装することで、複雑な変換ロジックに対応できます
次のステップとして、Bean Validationによる入力検証や、例外ハンドリングによるエラーレスポンスの統一を学ぶことで、より堅牢なREST APIを構築できます。
参考リンク#