Protobuf till Java-konverterare
Klistra in ett .proto-schema. Få enkla Java-klasser som du kan släppa direkt i ett projekt — publika fält, inga getters, lätta att anpassa.
Indata (.proto-schema)
Utdata (Java)
Vad det här verktyget gör
Du har ett Protocol Buffers-schema och en Java-tjänst som konsumerar dessa meddelanden — kanske via gRPC, kanske via JSON över HTTP. Att köra officiella protoc med Java-pluginen ger dig genererade klasser i Builder-pattern — utmärkta för produktion men tunga när du skissar, prototypar eller mappar JSON för hand mot en POJO. Den här konverteraren ger ut enkla Java-klasser — publika fält, vettiga defaults, en klass per meddelande, separata typer för enums.
Typmappningen följer hur handskriven Java ser ut i verkligheten: string → String, bool → boolean, int32/sint32/sfixed32 → int, int64/sint64/sfixed64 → long, double → double, float → float, bytes → byte[]. Java har inga unsigned numeriska typer, så uint32/fixed32 faller till int och uint64/fixed64 faller till long — fungerar för de flesta fall; om du faktiskt behöver översta biten, använd Integer.toUnsignedLong vid gränsen. repeated T blir List<T>, map<K, V> blir Map<K, V>, båda från java.util.
Fältnamn konverteras från snake_case (Protobuf-konvention) till camelCase (Java-konvention) — i linje med vad protoc skulle göra och med vad proto3 JSON-mappningen använder. Enums blir top-level public enum-typer med heltalsvärdet från ledningen bevarat som ett final-fält, så du kan round-trippa via protoc-genererad kod om du någon gång byter. Nästlade meddelanden plattas till top-level klasser så att varje kan flytta in i sin egen fil när du delar upp utdata. Allt körs i din webbläsare — ditt schema lämnar inte sidan.
Hur du använder det
Tre steg. Utdata är redo att släppas in i ett Java-projekt.
Klistra in ditt .proto-schema
Släpp schemat i den vänstra editorn. syntax = "proto3"; i toppen är OK men frivilligt. Parsern hanterar nästlade message-block, enum-deklarationer, oneof, map<K, V> och fältoptioner. import-direktiv känns igen men hoppas över — klistra in importerade typer inline om du behöver dem.
Fältnamnskonverteringen sker automatiskt: order_id i .proto blir orderId i Java. Meddelande- och enumnamn lämnas som de är (redan PascalCase).
Läs utdata
Till höger: ett enda .java-block med alla enums först, sedan alla klasser i deklarationsordning. Varje klass har publika fält med default-värden för primitiver (0, 0.0, false, ""), och referenstyper (List, Map, meddelandereferenser) blir kvar som null tills du fyller dem. Importerna java.util.List och java.util.Map läggs bara till när schemat behöver dem.
Släpp in i ditt projekt
Kopiera varje klass till sin egen .java-fil (Java kräver en publik klass per fil). Lägg till en package-deklaration och koppla sedan klasserna till din JSON-deserializer — Jackson tar publika fält som standard, och proto3 JSON-mappningen använder camelCase, så fältnamnen matchar redan. Om du föredrar getters/setters fixar IntelliJs "Encapsulate Fields"-refaktor det med ett tangenttryck.
När det faktiskt sparar tid
Skissa en Java-klient mot en gRPC-tjänst
Du gör en spike med en Java-klient mot en befintlig gRPC-backend — kanske en Spring Boot-tjänst, kanske en Quarkus — och du vill inte sätta upp den fulla protoc Maven- eller Gradle-pluginen än. Klistra in schemat, släpp klasserna i src/main/java/dto, deserialisera JSON-svaret med Jackson, leverera prototypen.
Handskriva DTO:er som matchar en proto
Ditt team använder Protobuf som sanningskälla på ledningen, men den konsumerande Java-tjänsten behöver bara tre eller fyra fält och du vill inte ha ett Message/Builder-beroende. Klistra in schemat, ta bort fälten du inte behöver, du har en enkel DTO som kompilerar fristående.
Granska en Protobuf-API-ändring
En backend-kollega lade till fält i ett meddelande. Du vill se hur det påverkar Java-POJO:n utan att köra bygget. Klistra in nya .proto, diffa Java-utdata mot dina nuvarande klasser, lämna en fokuserad granskningskommentar.
Dubbelkolla utdata från protoc
Ditt bygge använder den officiella protoc Java-pluginen som producerar klasser i Builder-pattern. Klistra in schemat här för en ren referens på hur enkel Java ser ut, användbart för dokumentation, onboarding eller för Kotlin-kollegor som föredrar data classes.
Vanliga frågor
Skickas mitt schema någonstans?
Nej. Parsern och Java-emitter:n körs helt i din webbläsare som JavaScript. Öppna DevTools och titta på Network-fliken medan du klistrar in — noll requests. Användbart när schemat innehåller interna paketsökvägar, typnamn eller annat som du inte vill skicka till en tredjepartstjänst.
Varför publika fält och inte getters/setters?
Två skäl. För det första, utdata är tänkt som en startpunkt du anpassar — publika fält är det minsta som kompilerar, och du kan alltid köra "Encapsulate Fields" i din IDE. För det andra, den vanligaste konsumenten är Jackson-deserialisering, som funkar direkt på publika fält. Om du behöver en record, oföränderlig typ eller Lombok @Data-klass, klistra in utdata och refaktorera.
Hur hanteras uint32 och uint64?
Java har inga unsigned heltalstyper, så uint32/fixed32 mappas till int och uint64/fixed64 till long. För värden som ryms i det signed intervallet fungerar det fint; för värden över Integer.MAX_VALUE eller Long.MAX_VALUE ser du negativa tal. Standardlösningen är Integer.toUnsignedLong(x) vid gränsen, eller använd aritmetiska helpers från java.lang.Long — se Java 21 API-dokumentationen för unsigned-helpers.
Varför är int64-fält bara long, inte String?
TypeScript och JSON har ett precisionstak på 53 bitar, så proto3 JSON-spec:en kodar 64-bitars heltal som strängar för att bevara precisionen. Javas long är ett äkta 64-bitars signed heltal utan precisionsförlust, så vi behåller Java-typen som long. Om du deserialiserar JSON där servern redan kodat int64 som sträng, konfigurera Jackson med @JsonFormat eller en custom deserializer; den underliggande typen behöver inte ändras.
Hur hanteras nästlade meddelanden?
Varje nästlat meddelande plattas till en top-level klass. Java:s konvention är en publik klass per fil, så plana top-level typer är lättare att dela upp när du kopierar varje klass till sin egen .java-fil. Om du hellre vill ha statiska inre klasser (stilen protoc ger ut), klistra in utdata och flytta de nästlade klasserna in i sin förälder — fältreferenserna använder redan leaf-namnet och löser sig så fort de hamnar i samma scope.
Är fält markerade som optional?
Nej — proto3-fält har alltid en default i wire-formatet, så primitiva fält initialiseras till sitt Java-nollvärde (0, 0.0, false, ""). Referenstyper (List, Map, nästlade meddelanden, byte[]) startar som null; kom ihåg att initialisera dem innan du lägger till element. Om du vill ha explicita Optional<T>-wrappers är det ett manuellt steg.
Hanterar den oneof?
Varje oneof-fält emitteras som ett vanligt klassfält. Utdata tvingar inte fram det "exakt ett"-villkor som oneof implicerar — för det skulle du behöva en sealed typhierarki eller en runtime-kontroll, och inget av det passar en enkel POJO. Om du vill ha striktare modellering, ta utdata och konvertera oneof-fälten till ett sealed interface med en record per fall.
Kan jag använda dessa klasser med den officiella protobuf-java-runtimen?
Inte direkt — den officiella runtimen förväntar sig klasser genererade av protoc med Builder, parseFrom och resten av com.google.protobuf.MessageOrBuilder-kontraktet. Klasserna från det här verktyget är enkla POJO:er, avsedda för JSON-serialisering (Jackson, Gson, Moshi). För det binära wire-formatet vill du fortfarande ha den officiella codegen — se Java-tutorialen för uppsättning.
Relaterade verktyg
Om du jobbar med Protobuf, JSON och Java passar dessa bra ihop: