• spring mvc 4.1支持protobuf converters


    最近公司有个项目需要和c++做信息交换,现在流行比较流行http+protobuf方式,一是比较简单学习成本低,二是信息的压缩比例比较好,节省带宽。

    经过调研spring 4.1以后开始支持protobuf HttpMessageConverter 详细的配置如下:

    • pom.xml配置:
    <dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>2.5.0</version>
    </dependency>
    <dependency>
    <groupId>com.googlecode.protobuf-java-format</groupId>
    <artifactId>protobuf-java-format</artifactId>
    <version>1.2</version>
    </dependency>
    还有要引入spring核心包及spring mvc包 版本4.1.6.RELEASE,如果不知道怎么引入,百度一下

    配置portoc插件,也可以不用这个插件,得需要自己用protoc.exe生产java文件
    <plugin>
    <groupId>com.google.protobuf.tools</groupId>
    <artifactId>maven-protoc-plugin</artifactId>
    <version>0.1.10</version>
    <executions>
    <execution>
    <id>generate-sources</id>
    <goals>
    <goal>compile</goal>
    </goals>
    <phase>generate-sources</phase>
    <configuration>
    <protoSourceRoot>${basedir}/src/main/proto/</protoSourceRoot>
    <includes>
    <param>**/*.proto</param>
    </includes>
    </configuration>
    </execution>
    </executions>
    <configuration>
    <protocExecutable>D:/dev/protoc.exe</protocExecutable><!--protoc.exe文件地址,使用2.5版本-->
    </configuration>
    </plugin>
    • springmvc-servlet.xml配置
    <mvc:annotation-driven>
    <mvc:message-converters>
        <!--看了一下源码,客户端请求类型必须设置成application/x-protobuf采用用这个类来解析实体

    <bean class="org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter">
            </bean>
    </mvc:message-converters>
    </mvc:annotation-driven>
    • user.proto文件,目录/src/main/proto/和protoc插件配置路径保持一致,如果不想用插件可以自己用protoc.exe生成java文件,可以参见protobuf使用
    package com.my.pb;

    option java_package = "com.my.pb";
     option java_outer_classname = "UserProto";

    message User {
    optional int64 id = 1;
    optional string name = 2;
    message PhoneNumber {
    required string number = 1;
    }
    repeated PhoneNumber phone = 4;
    }
    • controller类
    @Controller
    public class ProtobufController{

    @RequestMapping(value = "/proto/write1",method= RequestMethod.POST)
    public ResponseEntity<UserProto.User> protoWrite1(RequestEntity<UserProto.User> requestEntity) {
    //System.out.println("server=== ");
    UserProto.User user = requestEntity.getBody();
    System.out.println("server=== " + user);
    return ResponseEntity.ok(user);
    }
    }
    • 客户端测试代码,使用Apache的httpclient进行测试
    @Test
    public void testWrite() throws IOException {
    CloseableHttpClient httpclient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(baseUri+"/proto/write1");

    UserProto.User user = UserProto.User.newBuilder().setId(1).setName("zhangsan").addPhone(UserProto.User.PhoneNumber.newBuilder().setNumber("18611163408")).build();//构造

    ByteArrayInputStream inputStream = new ByteArrayInputStream(user.toByteArray());
    InputStreamEntity inputStreamEntity = new InputStreamEntity(inputStream);

        //这两行很重要的,是告诉springmvc客户端请求和响应的类型,指定application/x-protobuf类型,spring会用ProtobufHttpMessageConverter类来解析请求和响应的实体
            httpPost.addHeader("Content-Type","application/x-protobuf");
    httpPost.addHeader("Accept", "application/x-protobuf");

         httpPost.setEntity(inputStreamEntity);
    CloseableHttpResponse response2 = httpclient.execute(httpPost);

    try {
    System.out.println(response2.getStatusLine());
    HttpEntity entity2 = response2.getEntity();

    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    entity2.writeTo(buf);
    System.out.println(new String(buf.toByteArray())+"#################");
    UserProto.User user2 = UserProto.User.parseFrom(buf.toByteArray());
    System.out.println(user2);
    } finally {
    response2.close();
    }
    }
    • 总结:
    当时调试的时候试了很多次,响应总是被转成xml类型,最后看了源码才发现客户端要设置httpPost.addHeader("Accept", "application/x-protobuf");
    其实也可以自己实现HttpMessageConverter,也不是很麻烦,本人比较懒,有现成的东西不太爱闭门造车轮。
    参考文献:
    http://jinnianshilongnian.iteye.com/blog/2107205
    http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/


  • 相关阅读:
    单位根反演
    安卓第十三天笔记-服务(Service)
    安卓第十二天笔记-广播
    安卓第十一天笔记-Intent与inter-filter配置
    安卓第十天笔记-fragment
    安卓第九天笔记-Activity
    安卓第八天笔记--网络编程二
    安卓第七天笔记--网络编程一
    安卓第六天笔记--ListView
    安卓第五天笔记-对话框
  • 原文地址:https://www.cnblogs.com/lishanlin/p/4470731.html
Copyright © 2020-2023  润新知