springboot使用protobuf协议序列化,网上找了半天没找到满意的结果,其实不用设置contentType,入参、出参均使用字节流形式。对于字节流可以自己在入参增加解密算法,出参增加加密算法。
下面是个简单的无加密实例:
1.maven
<protobuf.version>3.19.0</protobuf.version>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
</dependency>
<!--测试用-->
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
</dependency>
插件用于idea直接编译proto
<os.detected.classifier>windows-x86_64</os.detected.classifier>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
2.协议
syntax = "proto3";
option java_multiple_files = true;
package com.mm.proto;
import "common.proto";
message UserRequest {
oneof body {
LoginReq login = 1; // 登录
}
}
message UserResponse {
oneof body {
LoginRes login = 1; // 登录
}
}
message LoginReq {
string name = 1;
}
message LoginRes {
string name = 1;
}
3.Controller代码
@Slf4j
@RestController
public class ApiController {
@RequestMapping(value = "/api")
public byte[] apiRequest(@RequestBody byte[] bytes, HttpServletRequest httpServletRequest) throws Exception {
//入参
UserRequest userRequest = UserRequest.parseFrom(bytes);
LoginReq login = userRequest.getLogin();
//出参
LoginRes.Builder loginRes = LoginRes.newBuilder().setName(login.getName());
UserResponse.Builder builder = UserResponse.newBuilder().setLogin(loginRes);
UserResponse response = builder.build();
byte[] data = response.toByteArray();
return data;
}
}
4.测试
package com.changzhi.yyyy.controller;
import com.google.protobuf.GeneratedMessageV3;
import com.googlecode.protobuf.format.JsonFormat;
import com.mm.proto.LoginReq;
import com.mm.proto.UserRequest;
import com.mm.proto.UserResponse;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.HttpClients;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
/**
* @Description:
* @author: 小落
* @date: 2023年05月25日
*/
public class Main {
public static void main(String[] args) {
try {
URI uri = new URI("http", null, "192.168.110.50", 15000, "/ymapi/api", "", null);
HttpPost request = new HttpPost(uri);
UserRequest.Builder builder = UserRequest.newBuilder();
LoginReq.Builder builder2 = LoginReq.newBuilder();
builder2.setName("qqq");
builder.setLogin(builder2.build());
HttpResponse response = doPost(request, builder.build());
UserResponse res = UserResponse.parseFrom(response.getEntity().getContent());
System.err.println(res.getLogin().getName());
} catch (Exception e) {
e.printStackTrace();
}
}
public static HttpResponse doPost(HttpPost post, GeneratedMessageV3 message) throws
IOException {
HttpClient httpclient = HttpClients.createDefault();
String requestUrl = post.getURI().toString();
ByteArrayInputStream inputStream = new ByteArrayInputStream(message.toByteArray());
InputStreamEntity inputStreamEntity = new InputStreamEntity(inputStream);
post.setEntity(inputStreamEntity);
for (Header header : post.getAllHeaders()) {
System.out.println(header.getName() + ":" + header.getValue());
}
StringBuilder sb = new StringBuilder();
sb.append("curl -XPOST ");
for (Header header : post.getAllHeaders()) {
sb.append(" -H \"").append(header.getName()).append(":").append(header.getValue()).append("\"");
}
String jsonBody = JsonFormat.printToString(message);
jsonBody = jsonBody.replace("\"", "\\\"");
sb.append(" -d \"").append(jsonBody).append("\"");
sb.append(" ").append(requestUrl);
System.out.println(sb.toString());
return httpclient.execute(post);
}
}