Protobuf til Java-konverter
Lim inn et .proto-skjema. Få vanlige Java-klasser du kan slippe rett inn i et prosjekt — public-felter, ingen gettere, lette å tilpasse.
Inndata (.proto-skjema)
Utdata (Java)
Hva dette verktøyet gjør
Du har et Protocol Buffers-skjema og en Java-tjeneste som konsumerer disse meldingene — kanskje over gRPC, kanskje via JSON over HTTP. Å kjøre den offisielle protoc med Java-pluginen gir deg genererte klasser i Builder-stil — flotte for produksjon, men tunge når du skisserer, prototyper eller hånd-mapper JSON ned i en POJO. Denne konverteren spytter ut vanlige Java-klasser — public-felter, fornuftige defaults, én klasse per melding, separate typer for enums.
Typetilordningen følger det håndskrevet Java ser ut som i praksis: string → String, bool → boolean, int32/sint32/sfixed32 → int, int64/sint64/sfixed64 → long, double → double, float → float, bytes → byte[]. Java har ingen unsigned numeriske typer, så uint32/fixed32 faller til int og uint64/fixed64 faller til long — greit for de fleste bruksområder; trenger du faktisk den øverste biten, bruk Integer.toUnsignedLong ved grensen. repeated T blir List<T>, map<K, V> blir Map<K, V>, begge fra java.util.
Feltnavn konverteres fra snake_case (Protobuf-konvensjon) til camelCase (Java-konvensjon) — i tråd med det protoc ville gjort, og det proto3 JSON-tilordningen bruker. Enums blir til top-level public enum-typer med heltallsverdien fra wire bevart som et final-felt, slik at du kan round-trippe gjennom protoc-generert kode hvis du noen gang bytter over. Nestede meldinger flates ut til top-level klasser, slik at hver kan flytte inn i sin egen fil når du deler opp utdata. Alt kjører i nettleseren din — skjemaet ditt forlater ikke siden.
Slik bruker du det
Tre steg. Utdata er klar til å slippes inn i et Java-prosjekt.
Lim inn .proto-skjemaet ditt
Slipp skjemaet i den venstre editoren. syntax = "proto3"; på toppen er greit men valgfritt. Parseren håndterer nestede message-blokker, enum-deklarasjoner, oneof, map<K, V> og feltvalg. import-direktiver gjenkjennes men hoppes over — lim inn importerte typer inline hvis du trenger dem.
Feltnavnkonvertering skjer automatisk: order_id i .proto blir orderId i Java. Meldings- og enumnavn beholdes som de er (allerede PascalCase).
Les utdata
Til høyre: én enkelt .java-blokk med alle enums først, deretter alle klasser i deklarasjonsrekkefølge. Hver klasse har public-felter med default-verdier for primitiver (0, 0.0, false, ""), og referansetyper (List, Map, meldingsreferanser) står som null til du fyller dem. Importene java.util.List og java.util.Map legges kun til når skjemaet trenger dem.
Slipp inn i prosjektet ditt
Kopier hver klasse til sin egen .java-fil (Java krever én public-klasse per fil). Legg til en package-deklarasjon, og koble så klassene til JSON-deserializeren etter eget valg — Jackson plukker opp public-felter som standard, og proto3 JSON-tilordningen bruker camelCase, så feltnavnene matcher allerede. Foretrekker du gettere/settere, klarer IntelliJ sin "Encapsulate Fields"-refaktor det med ett tastetrykk.
Når det faktisk sparer tid
Skissere en Java-klient mot en gRPC-tjeneste
Du gjør en spike med en Java-klient mot en eksisterende gRPC-backend — kanskje en Spring Boot-tjeneste, kanskje en Quarkus — og du vil ikke sette opp den fulle protoc Maven- eller Gradle-pluginen ennå. Lim inn skjemaet, slipp klassene i src/main/java/dto, deserialiser JSON-svaret med Jackson, send prototypen.
Håndlage DTO-er som matcher en proto
Teamet ditt bruker Protobuf som sannhetskilde på wire, men den konsumerende Java-tjenesten trenger bare tre eller fire felter, og du vil ikke ha en Message/Builder-avhengighet. Lim inn skjemaet, slett feltene du ikke trenger, og du har en vanlig DTO som kompilerer frittstående.
Gjennomgå en Protobuf-API-endring
En backend-kollega la til felter i en melding. Du vil se hvordan det påvirker Java-POJO-en uten å kjøre byggingen. Lim inn det nye .proto, diff Java-utdata mot dine nåværende klasser, legg igjen en fokusert gjennomgangskommentar.
Kryssjekke utdata fra protoc
Byggingen din bruker den offisielle protoc Java-pluginen, som produserer klasser i Builder-stil. Lim inn skjemaet her for en ren referanse på hvordan vanlig Java ser ut — nyttig for dokumentasjon, onboarding eller for Kotlin-kolleger som foretrekker data classes.
Vanlige spørsmål
Sendes skjemaet mitt noe sted?
Nei. Parseren og Java-emitteren kjører helt i nettleseren din som JavaScript. Åpne DevTools og se på Network-fanen mens du limer inn — null requests. Nyttig når skjemaet inneholder interne pakkestier, typenavn eller noe annet du helst ikke vil sende til en tredjepartstjeneste.
Hvorfor public-felter og ikke gettere/settere?
To grunner. For det første er utdata ment som et utgangspunkt du tilpasser — public-felter er det minste som kompilerer, og du kan alltid kjøre "Encapsulate Fields" i IDE-en din. For det andre er den vanligste konsumenten Jackson-deserialisering, som virker rett på public-felter. Trenger du en record, en uforanderlig type eller en Lombok @Data-klasse, lim inn utdata og refaktorer.
Hvordan håndteres uint32 og uint64?
Java har ingen unsigned heltallstyper, så uint32/fixed32 tilordnes int og uint64/fixed64 til long. For verdier som ligger innenfor det signed-intervallet, fungerer det greit; for verdier over Integer.MAX_VALUE eller Long.MAX_VALUE ser du negative tall. Standardløsningen er Integer.toUnsignedLong(x) ved grensen, eller bruk aritmetiske helpers fra java.lang.Long — se Java 21 API-dokumentasjonen for unsigned-helpers.
Hvorfor er int64-felter bare long, ikke String?
TypeScript og JSON har et presisjonstak på 53 bit, så proto3 JSON-spec-en koder 64-bits heltall som strings for å bevare presisjonen. Javas long er et ekte 64-bits signed heltall uten presisjonstap, så vi beholder Java-typen som long. Hvis du deserialiserer JSON der serveren allerede har kodet int64 som streng, konfigurer Jackson med @JsonFormat eller en custom deserializer; den underliggende typen trenger ikke å endres.
Hvordan håndteres nestede meldinger?
Hver nestet melding flates ut til en top-level klasse. Java-konvensjonen er én public-klasse per fil, så flate top-level typer er enklere å dele opp når du kopierer hver klasse til sin egen .java-fil. Vil du heller ha statiske indre klasser (stilen protoc spytter ut), lim inn utdata og flytt de nestede klassene inn i forelderen sin — feltreferansene bruker allerede leaf-navnet og resolver så snart de havner i samme scope.
Er felter merket som optional?
Nei — proto3-felter har alltid en default i wire-formatet, så primitive felter initialiseres til Java-nullverdien sin (0, 0.0, false, ""). Referansetyper (List, Map, nestede meldinger, byte[]) starter som null; husk å initialisere dem før du legger til elementer. Vil du ha eksplisitte Optional<T>-wrappere, er det et manuelt steg.
Håndterer den oneof?
Hvert oneof-felt sendes ut som et vanlig klassefelt. Utdata håndhever ikke "nøyaktig én"-betingelsen som oneof innebærer — for det ville du trengt et sealed type-hierarki eller en runtime-sjekk, og ingen av delene passer en vanlig POJO. Vil du ha strammere modellering, ta utdata og konverter oneof-feltene til et sealed interface med én record per tilfelle.
Kan jeg bruke disse klassene med den offisielle protobuf-java-runtimen?
Ikke direkte — den offisielle runtimen forventer klasser generert av protoc med Builder, parseFrom og resten av com.google.protobuf.MessageOrBuilder-kontrakten. Klassene fra dette verktøyet er vanlige POJO-er, ment for JSON-serialisering (Jackson, Gson, Moshi). For binært wire-format vil du fortsatt ha den offisielle codegen — se Java-tutorialen for oppsettet.
Relaterte verktøy
Hvis du jobber med Protobuf, JSON og Java, passer disse godt sammen: