我正在使用 gRPC 应用程序并构建一个简单的应用程序。在文件下面。
syntax = "proto3";
option java_multiple_files = true;
package com.grpc;
message HelloRequest {
string firstName = 1;
string lastname = 2;
}
message HelloResponse {
string greeting = 1;
}
service HelloService {
rpc hello(HelloRequest) returns (HelloResponse);
}
Run Code Online (Sandbox Code Playgroud)
它正常生成文件
User.java -> generated from protoc compiler
userGrpc.java -> generated from protoc compiler
Run Code Online (Sandbox Code Playgroud)
GRPC服务.java
package GRPCService;
import java.io.IOException;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import user.UserService;
public class GPRCService {
public static void main(String[] args) throws IOException, InterruptedException {
Server server = …Run Code Online (Sandbox Code Playgroud) 核心问题是我想为子消息设置默认值。由于 proto3 不允许在 proto 文件中设置默认值。
示例 Protobuf
message Person {
int32 age = 1;
repeated Doggo doggos = 2;
}
message Doggo {
int32 rating = 1;
}
Run Code Online (Sandbox Code Playgroud)
串行器示例
object PersonSerializer : Serializer<Person> {
override val defaultValue: Person =
Person.getDefaultInstance().toBuilder()
.setAge(1)
.build()
override suspend fun readFrom(input: InputStream): Person {
try {
return Person.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}
override suspend fun writeTo(t: Person, output: OutputStream) {
t.writeTo(output)
}
}
Run Code Online (Sandbox Code Playgroud)
这可以将所有 Person 的默认年龄设置为 1。标准值为0。 …
项目中已经使用了一些案例类。这些类也用于光滑映射。这些类扩展了一些额外的特征。
我不想从*.proto描述中生成所有这些类。
有机会扩展它们protobuf吗?或者我应该为它们使用包装器。这些包装器将在其中进行描述*.proto并从中生成。
我创建了一个原型如下:
syntax = "proto3";
option java_package = "cn.com.cennavi.oem.common";
option java_outer_classname = "RInfoPB";
message RInfo {
string dataVersion = 1;
map<string, MapValue> map = 2;
}
message MapValue {
map<string, string> map = 1;
}
Run Code Online (Sandbox Code Playgroud)
我将数据(240mb)放在pb对象中,并将对象序列化为本地文件(590mb).大小增加了一倍.为什么会这样?
接下来,我将本地文件转换为pb对象,Xms和Xmx都是5g.最后,我得到了一个outofmemory异常.
使用有问题吗?
BTW:protobuf.jar的版本是3.6.0
请帮帮忙~~
堆栈跟踪
[root @ localhost test] #java -Xms5g -Xmx5g -jar ProtobufTester.jar /APP/midmif/out_bak/Rbeijing_dir322.rinf
?????, ?? [488] ms, ?? [621043338] ~
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at com.google.protobuf.CodedInputStream$ArrayDecoder.readStringRequireUtf8(CodedInputStream.java:845)
at com.google.protobuf.WireFormat$Utf8Validation$2.readString(WireFormat.java:196)
at com.google.protobuf.WireFormat.readPrimitiveField(WireFormat.java:245)
at com.google.protobuf.FieldSet.readPrimitiveField(FieldSet.java:581)
at com.google.protobuf.MapEntryLite.parseField(MapEntryLite.java:135)
at com.google.protobuf.MapEntryLite.parseEntry(MapEntryLite.java:182)
at com.google.protobuf.MapEntry.<init>(MapEntry.java:106) …Run Code Online (Sandbox Code Playgroud) 我正在学习关于使用 grpc 的教程,我应该使用插件来生成源代码,但我坚持如何使用 --grpc_out 和 --plugin 标志。
以下是当前的挑战。

如果我不使用这些插件标志 (--plugin,--grpc_out) 我的代码可以用这个命令生成
protoc -I /proto --java_out /hello/grpc/grpc/revamp/services /proto/messages.proto
以上工作正常
添加标志,使用从混淆 1 下载的插件会使用此命令引发此错误;
protoc -I /proto --java_out /hello/grpc/grpc/revamp/services /proto/messages.proto --grpc_out /hello/grpc/grpc/revamp/services --plugin=protoc-gen-grpc=/proto/ lib/protoc-gen-grpc-java-1.19.0-osx-x86_64.exe
--grpc_out: protoc-gen-grpc: 插件失败,状态码为 1。
有没有人在 osx 上使用过这个插件?,谁能帮忙看看我做错了什么。
提前致谢
我的 Java 服务中有一个 POST 端点,需要 protobuf 3 有效负载。该服务由发送 protobuf 有效负载的其他服务使用。我想进行一些调试并通过curl命令将 protobuf 有效负载发送到服务,但是,我不知道如何构建这样的有效负载,因为它是二进制协议。
我想将 spring boot 与 protobuf 一起使用。简而言之,我编写了具有以下结构的演示代码;
RestController->获取实体->Postgres DB Repo->实体到protobuf对象->返回protobuf对象
pom 原型依赖;
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.12.4</version>
</dependency>
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.13.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
原型文件
syntax = "proto3";
package demo;
option java_package = "demo.model";
option java_outer_classname = "DemoProtos";
message DemoDto {
int64 id = 1;
string description = 2;
}
Run Code Online (Sandbox Code Playgroud)
gen.sh 文件
#!/usr/bin/env bash
SRC_DIR=`pwd`
DST_DIR=`pwd`/../src/main/
echo source: $SRC_DIR
echo destination root: $DST_DIR
function gen(){
D=$1
echo $D
OUT=$DST_DIR/$D
mkdir -p $OUT
sudo protoc -I=$SRC_DIR --${D}_out=$OUT $SRC_DIR/demo.proto
} …Run Code Online (Sandbox Code Playgroud) 我需要将 protobuf 消息转换为 java 中的 JSON 字符串。为此,我按照文档的建议使用以下 API(https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/util/JsonFormat.Printer.html)
String jsonString = JsonFormat.printer().includingDefaultValueFields().print(protobufMessage);
Run Code Online (Sandbox Code Playgroud)
这对于简单的字符串来说效果很好,但是,当我的字符串包含特殊字符(如 &、单引号等)时,JsonFormat 中的 gson.toJson() 方法会将特殊字符转换为八进制格式。例如,“A&BC”将转换为“A\u0026BC”。此外,生成的字符串还附加了一个额外的反斜杠。所以最终“A&BC”被转换为字符串“A\\u0026BC”。
如果它是“A\u0026BC”,那么我可以转换为字节数组并用它形成一个字符串。但由于额外的反斜杠我无法这样做。
目前我使用的是 protobuf 版本 3.7.1,我尝试升级并检查是否有最新的 API 可用,但没有帮助。我在网上搜索但没有找到任何参考(JSONFormat.printToString也报告了类似的问题,但此API在更高版本中被删除。https: //github.com/carlomedas/protobuf-java-format/issues/16)。如果您遇到此问题,有人可以在这里提供帮助吗?
我com.google.protobuf在我的项目中使用 gradle 插件从 proto 文件生成 java 类。下面是我的 build.gradle,它运行良好。
buildscript {
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.18'
}
}
plugins {
id 'java'
id 'com.google.protobuf' version '0.8.18'
}
repositories {
mavenCentral()
mavenLocal()
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation('io.grpc:grpc-netty-shaded:1.45.1')
implementation('io.grpc:grpc-stub:1.45.1')
implementation('io.grpc:grpc-protobuf:1.45.1')
implementation 'javax.annotation:javax.annotation-api:1.3.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.20.0"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.45.1'
}
}
generateProtoTasks { …Run Code Online (Sandbox Code Playgroud) I don't understand why an optional field (like middle_name in the example bellow), is not nullable in the kotlin generated representation while in golang and rust is properly nullable (or optional).
syntax = "proto3";
message User{
string id = 1;
string name = 2;
optional string middle_name = 3;
string last_name = 4;
}
Run Code Online (Sandbox Code Playgroud)
Kotlin generated code
...
public fun hasMiddleName(): kotlin.Boolean{...}
public var middleName: kotlin.String{...}
...
Run Code Online (Sandbox Code Playgroud)
Rust generated code
...
pub middle_name: ::std::option::Option<::std::string::String>,
...
Run Code Online (Sandbox Code Playgroud)
Golang generated code
...
MiddleName …Run Code Online (Sandbox Code Playgroud)