基于http的protobuf服务实现

雨点打透心脏的1/2处 2024-02-23 08:12 100阅读 0赞

本文介绍在http协议中,使用protobuf格式进行二进制数据通信。双方需设置http的header中ContentType为application/x-protobuf。

1、springboot下实现protobuf:

1)pom.xml

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <!-- protobuf -->
  6. <dependency>
  7. <groupId>com.google.protobuf</groupId>
  8. <artifactId>protobuf-java</artifactId>
  9. <version>3.11.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.google.protobuf</groupId>
  13. <artifactId>protobuf-java-util</artifactId>
  14. <version>3.11.0</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>com.googlecode.protobuf-java-format</groupId>
  18. <artifactId>protobuf-java-format</artifactId>
  19. <version>1.2</version>
  20. </dependency>
  21. <!-- 网络请求依赖 -->
  22. <dependency>
  23. <groupId>org.apache.httpcomponents</groupId>
  24. <artifactId>httpclient</artifactId>
  25. <version>4.5.2</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.apache.httpcomponents</groupId>
  29. <artifactId>httpcore</artifactId>
  30. <version>4.4</version>
  31. </dependency>

2)user_login.proto

  1. syntax = "proto3";
  2. // 转成java后所在包
  3. option java_package = "com.tencent.rating.audi_model_api.pb";
  4. // 转成java后的类名
  5. option java_outer_classname = "MessageUserLogin";
  6. // 转java后生成一个java文件
  7. option java_multiple_files = false;
  8. message MessageUserLoginRequest {
  9. string username = 1;
  10. string password = 2;
  11. }
  12. message MessageUserLoginResponse {
  13. string access_token = 1;
  14. string username = 2;
  15. }

编译:

  1. protoc --proto_path=/data/ --java_out=./ /data/user_login.proto

3)创建springboot工程,编写config:

  1. @Configuration
  2. public class WebConfig {
  3. @Bean
  4. ProtobufHttpMessageConverter protobufHttpMessageConverter() {
  5. return new ProtobufHttpMessageConverter();
  6. }
  7. /**
  8. * protobuf 反序列化 可以不用配置
  9. */
  10. // @Bean
  11. // RestTemplate restTemplate(ProtobufHttpMessageConverter protobufHttpMessageConverter) {
  12. // return new RestTemplate(Collections.singletonList(protobufHttpMessageConverter));
  13. // }
  14. }

4)编写contorller:

  1. import java.util.UUID;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestBody;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6. import com.tencent.rating.audi_model_api.pb.MessageUserLogin;
  7. @Controller
  8. public class PbTestController {
  9. @RequestMapping(value = "/pbtest", produces = "application/x-protobuf")
  10. @ResponseBody
  11. public MessageUserLogin.MessageUserLoginResponse getPersonProto(@RequestBody MessageUserLogin.MessageUserLoginRequest request) {
  12. System.out.println("request:" + request.toString());
  13. MessageUserLogin.MessageUserLoginResponse.Builder builder = MessageUserLogin.MessageUserLoginResponse.newBuilder();
  14. builder.setAccessToken(UUID.randomUUID().toString()+"_res");
  15. builder.setUsername(request.getUsername()+"_res");
  16. return builder.build();
  17. }
  18. }

然后启动sprinboot工程。监听8080端口

5)编写客户端请求:

  1. public class PbTest {
  2. public static void main(String...strings) {
  3. try {
  4. String uri = "http://127.0.0.1:8080/clue/pbtest";
  5. MessageUserLogin.MessageUserLoginRequest.Builder builder = MessageUserLogin.MessageUserLoginRequest.newBuilder();
  6. builder.setUsername("tom");
  7. builder.setPassword("123456");
  8. HttpResponse response = doPost(uri, builder.build().toByteArray());
  9. MessageUserLogin.MessageUserLoginResponse messageUserLoginResponse = MessageUserLogin.MessageUserLoginResponse.parseFrom(response.getEntity().getContent());
  10. System.out.println("response:" + messageUserLoginResponse.toString());
  11. System.err.println(messageUserLoginResponse.getAccessToken());
  12. } catch (Exception e) {
  13. }
  14. }
  15. private static HttpResponse doPost(String uri, byte[] bytes) throws Exception {
  16. CloseableHttpResponse closeableHttpResponse = null;
  17. CloseableHttpClient httpclient = HttpClients.createDefault();
  18. try {
  19. HttpPost post = new HttpPost(uri);
  20. ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
  21. InputStreamEntity inputStreamEntity = new InputStreamEntity(inputStream);
  22. post.setEntity(inputStreamEntity);
  23. post.addHeader("Content-Type", "application/x-protobuf");
  24. closeableHttpResponse = httpclient.execute(post);
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. } finally {
  28. // httpclient.close();
  29. }
  30. return closeableHttpResponse;
  31. }
  32. }

2、servlet下实现protobuf:

1)创建servlet项目,编写servlet代码:

  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.util.UUID;
  4. import javax.servlet.ServletOutputStream;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import servlet_test.pb.MessageUserLogin;
  10. import servlet_test.pb.MessageUserLogin.MessageUserLoginRequest;
  11. import servlet_test.pb.MessageUserLogin.MessageUserLoginResponse.Builder;
  12. @WebServlet(urlPatterns = {"/syncServlet2"})
  13. public class SyncServlet2 extends HttpServlet {
  14. private static final long serialVersionUID = 1L;
  15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
  16. //解析请求
  17. InputStream stream=request.getInputStream();
  18. MessageUserLoginRequest mlr = MessageUserLogin.MessageUserLoginRequest.parseFrom(stream);
  19. System.out.println(mlr.toString());
  20. //创建响应
  21. Builder newBuilder = MessageUserLogin.MessageUserLoginResponse.newBuilder();
  22. newBuilder.setAccessToken(UUID.randomUUID().toString()+"_res");
  23. newBuilder.setUsername(mlr.getUsername()+"_res");
  24. response.setCharacterEncoding("UTF-8");
  25. ServletOutputStream out = response.getOutputStream();
  26. out.write(newBuilder.build().toByteArray());
  27. out.flush();
  28. out.close();
  29. }
  30. }

2)客户端测试:

同上。

发表评论

表情:
评论列表 (有 0 条评论,100人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Nginx实现Http服务

    一 概述 Nginx的默认端口为80端口。Http服务是指通过Http服务来访问资源,如当我们的图片存放在目录/opt/temp/images中,对于普通的图片而言是无法