이 JSON to Java 변환기는 샘플 JSON 값을 읽어 getter와 setter가 있는 기존 POJO가 아니라 Java record 선언으로 작성합니다. 중첩 객체는 각각 별도 record가 되고, 키는 camelCase 컴포넌트가 되며, Java 이름이 키와 다를 때만 @JsonProperty("original_key")가 붙습니다. 배열은 래퍼 타입 요소를 가진 List<T>가 되어서 [1, 2, 3]은 List<Long>입니다.
record는 Java 16 이상이 필요하고 Jackson은 2.12부터 record를 바인딩합니다. 배열의 모든 요소는 키의 합집합을 가진 record 하나로 병합됩니다. 일부 요소에 없거나 일부에서 null인 키는 원시 타입이 null일 수 없으므로 래퍼 타입(Long, Double, Boolean)이 됩니다. 루트는 객체 또는 배열입니다.
입력은 브라우저 안에서 변환되고 어디로도 전송되지 않습니다. 입력 한도는 20 MiB입니다. 페이지에는 루트 타입 이름, 패키지, Jackson 어노테이션 옵션이 있고, 내려받는 파일은 루트 이름을 따라 기본값 Payload.java가 됩니다.
사용 방법
JSON 객체 또는 배열 붙여 넣기
페이로드를 붙여 넣거나 예제(API 응답, 중첩 배열, 엣지 케이스) 중 하나를 불러옵니다. 최상위가 문자열·숫자·불리언·null 단독 값이면 이름을 붙일 타입이 없어 오류가 표시됩니다.
옵션 설정
루트 타입 이름(기본
Payload)과 패키지(기본은 비어 있어package줄이 없음)를 입력하고, Jackson @JsonProperty를 켜거나 끕니다.출력 읽기
import가 먼저 나오고, 이어서 public 루트 record, 그다음 중첩 record가 처음 만난 순서대로 나옵니다. 루트가 배열이면 루트 record 대신
// The root JSON value is List<...>주석이 나옵니다.import 확인
com.fasterxml.jackson.annotation.JsonProperty는 Jackson 옵션이 켜져 있고 이름이 바뀐 컴포넌트가 하나 이상일 때만 나옵니다.java.util.List는 컴포넌트 타입으로 리스트가 선언될 때만 나옵니다.복사하거나 .java로 저장
루트 record가
public이므로Payload.java처럼 루트 이름으로 파일을 저장합니다. 중첩 record는 패키지 전용이라 같은 파일에 둘 수 있습니다.
작동 원리
JSON과 Java 타입 대응
값이 항상 있으면 Java 원시 타입을, 없거나 null일 수 있으면 래퍼 클래스를 씁니다. 절댓값 2^63 미만인 정수 표기는 long 또는 Long, 소수점·지수 표기와 소수 값 및 2^63 이상의 정수는 double 또는 Double입니다. 제네릭 안의 리스트 요소는 항상 박싱됩니다.
| JSON 값 | Java 타입 | 비고 |
|---|---|---|
| 문자열 | String | |
| true / false | boolean | 일부 요소에서 null이거나 없을 때, 그리고 List 안에서는 Boolean |
| 2^63 미만의 정수 표기 | long | nullable, 선택, List 안에서는 Long. int는 쓰지 않음 |
| 소수가 있는 숫자 | double | 1과 2.5가 같이 나오는 위치는 double |
| 모든 샘플에서 null | Object | 타입 정보 없음 |
| 객체 | record Name(...) {} | 루트는 public, 중첩은 패키지 전용 |
| 배열 | List<T> | T는 모든 요소를 병합한 타입, 예: List<Long> |
| 빈 배열 또는 혼합 배열 | List<Object> | [1, "a"]는 공통 타입이 없음 |
| 빈 객체 | record Name() {} | 컴포넌트 없음 |
이름 규칙과 Jackson 어노테이션
컴포넌트 이름은 camelCase 경계와 영문·숫자가 아닌 문자에서 단어를 나눠 lowerCamelCase로 잇습니다. first_name은 firstName, HTTPServer는 httpServer가 됩니다. 숫자로 시작하면 field 접두사가 붙어 2fa는 field2fa입니다. Java 예약어와 record, sealed, permits, var, yield, true, false, null에는 밑줄이 붙습니다(class_, default_). 같은 이름이 되는 키는 2부터 번호가 붙습니다.
record 이름은 PayloadUser처럼 부모 이름에 키를 이은 PascalCase입니다. 리스트 요소 record는 키의 단수형을 씁니다. items는 PayloadItem, data는 PayloadDataItem입니다. @JsonProperty는 컴포넌트 이름이 키와 다를 때만 쓰므로 id에는 붙지 않습니다. Jackson 옵션을 끄면 어노테이션과 import가 빠지고, 이름이 바뀐 키는 더 이상 바인딩되지 않습니다.
@JsonProperty("first_name")
String firstName,
List<Long> scores,
Long qtyObjectMapper로 읽기
Payload p = new ObjectMapper().readValue(text, Payload.class);가 record를 채우고 writeValueAsString(p)가 다시 JSON을 만듭니다. 알 수 없는 속성은 기본적으로 예외를 던지므로, API에 키가 추가될 수 있다면 FAIL_ON_UNKNOWN_PROPERTIES를 false로 설정하세요.
long count 같은 원시 컴포넌트는 null을 담을 수 없습니다. Jackson은 JSON null을 FAIL_ON_NULL_FOR_PRIMITIVES를 켜지 않는 한 0으로 읽고, 키가 없을 때도 0이나 false가 됩니다. 그래서 변환기는 샘플 요소 중 하나라도 키가 null이거나 없으면 Long을 쓰고, 항상 있던 키에만 long을 남깁니다.
실제 예시
{"id":42,"user":{"name":"Ada","active":true},"roles":["admin","editor"]}import java.util.List;
public record Payload(
long id,
PayloadUser user,
List<String> roles
) {}
record PayloadUser(
String name,
boolean active
) {}루트만 public이므로 파일 이름은 Payload.java여야 합니다. 중첩 record는 패키지 전용입니다. 모든 이름이 키와 같아서 JsonProperty가 필요 없습니다.
{"first_name":"Ada","class":"A","default":true,"user-agent":"curl","2fa":false}import com.fasterxml.jackson.annotation.JsonProperty;
public record Payload(
@JsonProperty("first_name")
String firstName,
@JsonProperty("class")
String class_,
@JsonProperty("default")
boolean default_,
@JsonProperty("user-agent")
String userAgent,
@JsonProperty("2fa")
boolean field2fa
) {}컴포넌트는 camelCase입니다. Java 예약어에는 밑줄이 붙고, 이름이 바뀔 때마다 @JsonProperty가 원래 키를 유지합니다.
{"scores":[1,2,3],"flags":[true,false],"grid":[[1.5,2],[3]]}import java.util.List;
public record Payload(
List<Long> scores,
List<Boolean> flags,
List<List<Double>> grid
) {}제네릭에는 래퍼 타입이 필요해서 List<Long>, List<Boolean>, List<List<Double>>이 됩니다. grid 안의 2와 3은 소수와 합쳐져 Double이 됩니다.
{"orders":[{"id":1,"total":9.5,"coupon":null},{"id":2,"total":12,"note":"gift"}]}import java.util.List;
public record Payload(
List<PayloadOrder> orders
) {}
record PayloadOrder(
long id,
double total,
Object coupon,
String note
) {}두 주문을 모두 읽습니다. note는 두 번째에만 있어 String이고, id와 total은 둘 다 있어 원시 타입으로 남습니다(9.5와 12가 병합되어 total은 double). coupon은 모두 null이라 Object입니다.
[{"user_id":1},{"user_id":2,"email":"a@b.c"}]package com.acme.model;
// The root JSON value is List<UserListItem>
record UserListItem(
long userId,
String email
) {}옵션: 루트 타입 이름 user list, 패키지 com.acme.model, Jackson 끔. 배열 루트에는 자체 record가 없어서 루트 이름은 요소 record 이름 UserListItem과 파일 이름 UserList.java에만 나타납니다. Jackson을 끄면 userId에 어노테이션이 없어 user_id 키를 읽지 못합니다.
자주 하는 실수
샘플 하나로는 항상 있는 필드인지 알 수 없습니다
래퍼 타입은 붙여 넣은 요소 중 하나 이상에서 키가 없거나 null일 때만 나옵니다. 레코드가 하나뿐이면 전부 원시 타입이 되고, Jackson은 없는 키를 오류 없이 0이나 false로 바꿉니다. 값이 빠진 레코드를 포함해 여러 개를 붙여 넣으세요.
Jackson을 끄면 이름이 바뀐 키가 바인딩되지 않습니다
Jackson 옵션을 끄면
user_id같은 키는 어노테이션 없는userId컴포넌트가 됩니다.ObjectMapper는userId를 찾다가 데이터를 놓칩니다. 키를 대신 매핑해 주는 명명 전략을 쓰지 않는다면 옵션을 켜 두세요.2^63 미만의 정수 표기는 long입니다
절댓값 2^63 미만인 정수 표기는
long, 2^63 이상은double입니다.10.0과1e3도double입니다. 2^53을 넘는 정확한 ID는 문자열로 입력하고String이나BigInteger를 쓰세요.null뿐인 필드는 Object가 됩니다
붙여 넣은 모든 레코드에서 null인 키나 빈 배열은 타입 정보가 없어
Object또는List<Object>가 됩니다. 실제 타입을 알게 되면String,Long, record 등으로 바꾸세요.파일 하나에 public record는 하나
루트 record만
public이므로Payload.java처럼 그 이름으로 파일을 저장해야 합니다. 중첩 record는 패키지 전용이라 다른 패키지에서 쓰려면 별도 파일로 옮기세요. 루트 타입 이름을 바꾸면 파일 이름도 바뀝니다.충돌하는 이름은 합쳐지지 않고 번호가 붙습니다
한 객체의
user_id와userId는userId와userId2가 되고, 둘 다 자기 키를 가리키는@JsonProperty를 받습니다. 두 키가 정말 다른 필드인지 확인하세요.
자주 묻는 질문
getter와 setter가 있는 클래스도 만들어 주나요?
아니요. record만 만들기 때문에 Java 16 이상이 필요하고, 읽으려면 Jackson 2.12 이상이어야 합니다.
배열의 모든 요소를 읽나요?
네. 모든 요소의 객체를 키의 합집합을 가진 record 하나로 병합합니다. 일부 요소에 없거나 일부에서 null인 키는 래퍼 타입이 되고, 값의 타입이 서로 다른 키는 Object가 됩니다.
숫자가 int가 아니라 long인 이유는 무엇인가요?
절댓값 2^63 미만인 정수 표기는 long이고 제네릭이나 nullable에서는 Long입니다. 소수점·지수 표기와 소수 값 및 2^63 이상의 정수는 double 또는 Double입니다.
null 값은 어떤 타입이 되나요?
다른 값과 함께 나온 null은 래퍼 타입을 만듭니다(long이 Long이 되고 String은 그대로). 항상 null인 키는 Object입니다.
class나 default 같은 키는 어떻게 되나요?
뒤에 밑줄이 붙어 class_가 되고, Jackson이 켜져 있으면 @JsonProperty("class")가 원래 키로 되돌립니다.
루트 record 이름과 패키지를 바꿀 수 있나요?
네. 루트 타입 이름이 루트 record와 다운로드 파일 이름을 정하고, 패키지는 package 줄을 추가합니다. 중첩 타입 이름은 루트 이름에서 만들어집니다.
JSON이 업로드되나요?
아니요. 변환은 전부 브라우저에서 실행되며 입력 한도는 20 MiB입니다.
마지막 업데이트:
