Konwerter Protobuf do Javy
Wklej schemat .proto. Odbierz proste klasy Javy, które wrzucisz prosto do projektu — pola publiczne, bez getterów, łatwe do dostosowania.
Wejście (schemat .proto)
Wyjście (Java)
Co robi to narzędzie
Masz schemat Protocol Buffers i serwis Javy, który konsumuje te wiadomości — może przez gRPC, może przez JSON po HTTP. Uruchomienie oficjalnego protoc z wtyczką Javy daje wygenerowane klasy w pattern Builder — świetne na produkcję, ale ciężkie do szkicowania, prototypowania albo ręcznego mapowania JSON-a na POJO. Ten konwerter wypluwa proste klasy Javy — pola publiczne, sensowne wartości domyślne, jedna klasa na wiadomość, osobne typy dla enumów.
Mapowanie typów odpowiada temu, jak wygląda Java pisana ręcznie w realu: string → String, bool → boolean, int32/sint32/sfixed32 → int, int64/sint64/sfixed64 → long, double → double, float → float, bytes → byte[]. Java nie ma typów liczbowych bez znaku, więc uint32/fixed32 spadają do int, a uint64/fixed64 spadają do long — w większości przypadków to wystarcza; jeśli naprawdę potrzebujesz najwyższego bitu, użyj Integer.toUnsignedLong na granicy. repeated T staje się List<T>, map<K, V> staje się Map<K, V>, oba z java.util.
Nazwy pól są konwertowane z snake_case (konwencja Protobufa) na camelCase (konwencja Javy) — zgodnie z tym, co zrobiłby protoc i z tym, czego używa mapowanie JSON proto3. Enumy stają się typami public enum najwyższego poziomu z zachowaną wartością całkowitoliczbową z drutu jako pole final, więc możesz robić round-trip przez kod wygenerowany przez protoc, jeśli kiedyś się przesiądziesz. Zagnieżdżone wiadomości są spłaszczane do klas najwyższego poziomu, więc każda może trafić do własnego pliku, gdy podzielisz wynik. Wszystko działa w przeglądarce — twój schemat nie opuszcza strony.
Jak tego użyć
Trzy kroki. Wynik jest gotowy do wrzucenia do projektu Javy.
Wklej swój schemat .proto
Wrzuć schemat do lewego edytora. syntax = "proto3"; na górze jest OK, ale opcjonalne. Parser ogarnia zagnieżdżone bloki message, deklaracje enum, oneof, map<K, V> i opcje pól. Dyrektywy import są rozpoznawane, ale pomijane — wklej importowane typy inline, jeśli ich potrzebujesz.
Konwersja nazw pól dzieje się automatycznie: order_id w .proto staje się orderId w Javie. Nazwy wiadomości i enumów zostają jak są (już PascalCase).
Przeczytaj wynik
Po prawej: pojedynczy blok .java najpierw ze wszystkimi enumami, potem ze wszystkimi klasami w kolejności deklaracji. Każda klasa ma pola publiczne z wartościami domyślnymi dla typów prostych (0, 0.0, false, ""), a typy referencyjne (List, Map, refy do wiadomości) zostają jako null, dopóki ich nie wypełnisz. Importy java.util.List i java.util.Map są dodawane tylko wtedy, gdy schemat tego potrzebuje.
Wrzuć do swojego projektu
Skopiuj każdą klasę do własnego pliku .java (Java wymaga jednej publicznej klasy na plik). Dodaj deklarację package, potem podepnij klasy do swojego deserializatora JSON-a — Jackson domyślnie łapie pola publiczne, a mapowanie JSON proto3 używa camelCase, więc nazwy pól już pasują. Jeśli wolisz gettery/settery, refactor "Encapsulate Fields" w IntelliJ załatwi to jednym skrótem.
Kiedy to faktycznie oszczędza czas
Szkicowanie klienta Javy do serwisu gRPC
Robisz spike'a klienta Javy przeciwko istniejącemu backendowi gRPC — może serwis Spring Boot, może Quarkus — i nie chcesz jeszcze stawiać pełnej wtyczki protoc Mavena lub Gradle'a. Wklej schemat, wrzuć klasy do src/main/java/dto, zdeserializuj odpowiedź JSON Jacksonem, wystaw prototyp.
Pisanie ręcznie DTO pasujących do proto
Twój zespół używa Protobufa jako źródła prawdy na drucie, ale konsumujący serwis Javy potrzebuje tylko trzech-czterech pól i nie chcesz zależności Message/Builder. Wklej schemat, usuń pola, których nie potrzebujesz, masz proste DTO, które kompiluje się samodzielnie.
Review zmiany w API Protobufa
Kolega z backendu dodał pola do wiadomości. Chcesz zobaczyć, jak to wpływa na POJO Javy bez odpalania builda. Wklej nowy .proto, zrób diff wyniku Javy względem aktualnych klas, zostaw konkretny komentarz w review.
Krzyżowe sprawdzanie wyniku z protoc
Twój build używa oficjalnej wtyczki Javy do protoc, która produkuje klasy w pattern Builder. Wklej tu schemat dla czystej referencji, jak wygląda zwykła Java — przyda się do dokumentacji, onboardingu albo dla kolegów z Kotlina, którzy wolą data classes.
Częste pytania
Czy mój schemat jest gdzieś wysyłany?
Nie. Parser i emitter Javy działają w całości w przeglądarce jako JavaScript. Otwórz DevTools i obserwuj zakładkę Network podczas wklejania — zero żądań. Przydatne, gdy schemat zawiera wewnętrzne ścieżki paczek, nazwy typów albo cokolwiek, czego nie chcesz wysyłać do usługi trzeciej strony.
Dlaczego pola publiczne, a nie gettery/settery?
Dwa powody. Po pierwsze, wynik ma być punktem startu, który adaptujesz — pola publiczne to najmniejsze, co się kompiluje, a w każdej chwili możesz odpalić "Encapsulate Fields" w swoim IDE. Po drugie, najczęstszym konsumentem jest deserializacja Jackson, która działa od razu na polach publicznych. Jeśli potrzebujesz recordu, typu niemutowalnego albo klasy Lombok @Data, wklej wynik i zrefaktoruj.
Jak są obsługiwane uint32 i uint64?
Java nie ma typów całkowitych bez znaku, więc uint32/fixed32 mapują się na int, a uint64/fixed64 na long. Dla wartości mieszczących się w zakresie ze znakiem to działa OK; dla wartości powyżej Integer.MAX_VALUE albo Long.MAX_VALUE zobaczysz liczby ujemne. Standardowe rozwiązanie to Integer.toUnsignedLong(x) na granicy albo użycie pomocników arytmetycznych java.lang.Long — zajrzyj do dokumentacji API Javy 21 po pomocników bez znaku.
Dlaczego pola int64 są zwykłym long, a nie String?
TypeScript i JSON mają sufit precyzji 53 bitów, więc spec JSON proto3 koduje 64-bitowe inty jako stringi, żeby zachować precyzję. long w Javie to prawdziwy 64-bitowy całkowity ze znakiem bez utraty precyzji, więc trzymamy typ Javy jako long. Jeśli deserializujesz JSON-a, w którym serwer już zakodował int64 jako string, skonfiguruj Jacksona z @JsonFormat albo własnym deserializatorem; typ pod spodem nie musi się zmieniać.
Jak radzi sobie z zagnieżdżonymi wiadomościami?
Każda zagnieżdżona wiadomość jest spłaszczana do klasy najwyższego poziomu. Konwencja Javy to jedna publiczna klasa na plik, więc płaskie typy najwyższego poziomu są łatwiejsze do podziału, gdy kopiujesz każdą klasę do własnego pliku .java. Jeśli wolisz statyczne klasy wewnętrzne (styl, który emituje protoc), wklej wynik i przesuń zagnieżdżone klasy do wnętrza ich rodzica — referencje do pól używają już nazwy liścia i rozwiążą się, gdy znajdą się w tym samym scope.
Czy pola są oznaczane jako optional?
Nie — pola proto3 zawsze mają default w formacie drutu, więc pola prymitywne są inicjalizowane do swojej wartości zerowej Javy (0, 0.0, false, ""). Typy referencyjne (List, Map, zagnieżdżone wiadomości, byte[]) startują jako null; pamiętaj, żeby je zainicjalizować przed dodaniem elementów. Jeśli chcesz jawnych wrapperów Optional<T>, to ręczny krok.
Czy obsługuje oneof?
Każde pole oneof jest emitowane jako zwykłe pole klasy. Wynik nie wymusza ograniczenia "dokładnie jedno", które implikuje oneof — do tego potrzebowałbyś hierarchii sealed albo sprawdzenia w runtime, a żadne z tych nie pasuje do prostego POJO. Jeśli chcesz bardziej rygorystycznego modelowania, weź wynik i przekonwertuj pola oneof na sealed interface z jednym recordem na przypadek.
Czy mogę używać tych klas z oficjalnym runtime'em protobuf-java?
Nie bezpośrednio — oficjalny runtime oczekuje klas wygenerowanych przez protoc z Builder, parseFrom i resztą kontraktu com.google.protobuf.MessageOrBuilder. Klasy z tego narzędzia to proste POJO, przeznaczone do serializacji JSON (Jackson, Gson, Moshi). Do binarnego formatu drutu nadal chcesz oficjalnego codegena — zobacz tutorial Javy po setup.
Powiązane narzędzia
Jeśli pracujesz z Protobufem, JSON-em i Javą, te dobrze się komponują: