MYMONDAY.ai
서비스스튜디오도구데이터·포맷73CSS 생성기19색상·이미지10인코딩·보안10웹·SEO11개발·데브옵스10파일·내보내기18계산기6가이드

JSON to Java record 변환기

JSON 객체나 배열을 붙여 넣으면 camelCase 컴포넌트, 필요한 곳의 래퍼 타입, 이름이 바뀐 키의 @JsonProperty가 있는 Java record를 만듭니다.

  • 브라우저에서 처리
  • 가입 없음
  • 무료

도구 작업 공간

예제

옵션

JSON 키가 Java 이름과 다를 때 필요합니다.

JSON 입력

27줄435byte

결과

⌘/Ctrl + Enter로 복사
결과 · Payload.java
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

public record Payload(
    long id,
    String status,
    PayloadCustomer customer,
    List<PayloadItem> items,
    double total,
    @JsonProperty("shipped_at")
    String shippedAt,
    Object tracking
) {}

record PayloadCustomer(
    long id,
    String name,
    String email,
    boolean vip
) {}

record PayloadItem(
    String sku,
    String name,
    long qty,
    double price
) {}
타입3
크기473byte

이 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가 됩니다.

사용 방법

  1. JSON 객체 또는 배열 붙여 넣기

    페이로드를 붙여 넣거나 예제(API 응답, 중첩 배열, 엣지 케이스) 중 하나를 불러옵니다. 최상위가 문자열·숫자·불리언·null 단독 값이면 이름을 붙일 타입이 없어 오류가 표시됩니다.

  2. 옵션 설정

    루트 타입 이름(기본 Payload)과 패키지(기본은 비어 있어 package 줄이 없음)를 입력하고, Jackson @JsonProperty를 켜거나 끕니다.

  3. 출력 읽기

    import가 먼저 나오고, 이어서 public 루트 record, 그다음 중첩 record가 처음 만난 순서대로 나옵니다. 루트가 배열이면 루트 record 대신 // The root JSON value is List<...> 주석이 나옵니다.

  4. import 확인

    com.fasterxml.jackson.annotation.JsonProperty는 Jackson 옵션이 켜져 있고 이름이 바뀐 컴포넌트가 하나 이상일 때만 나옵니다. java.util.List는 컴포넌트 타입으로 리스트가 선언될 때만 나옵니다.

  5. 복사하거나 .java로 저장

    루트 record가 public이므로 Payload.java처럼 루트 이름으로 파일을 저장합니다. 중첩 record는 패키지 전용이라 같은 파일에 둘 수 있습니다.

작동 원리

JSON과 Java 타입 대응

값이 항상 있으면 Java 원시 타입을, 없거나 null일 수 있으면 래퍼 클래스를 씁니다. 절댓값 2^63 미만인 정수 표기는 long 또는 Long, 소수점·지수 표기와 소수 값 및 2^63 이상의 정수는 double 또는 Double입니다. 제네릭 안의 리스트 요소는 항상 박싱됩니다.

JSON 값Java 타입비고
문자열String
true / falseboolean일부 요소에서 null이거나 없을 때, 그리고 List 안에서는 Boolean
2^63 미만의 정수 표기longnullable, 선택, List 안에서는 Long. int는 쓰지 않음
소수가 있는 숫자double1과 2.5가 같이 나오는 위치는 double
모든 샘플에서 nullObject타입 정보 없음
객체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 qty

ObjectMapper로 읽기

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을 남깁니다.

실제 예시

문자열 List가 있는 중첩 객체
입력
{"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가 필요 없습니다.

이름이 바뀐 컴포넌트와 Jackson 어노테이션
입력
{"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입니다.

마지막 업데이트: