最近公司有個(gè)項(xiàng)目需要和c++做信息交換,現(xiàn)在流行比較流行http+protobuf方式,一是比較簡單學(xué)習(xí)成本低,二是信息的壓縮比例比較好,節(jié)省帶寬。
經(jīng)過調(diào)研spring 4.1以后開始支持protobufHttpMessageConverter 詳細(xì)的配置如下:
<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插件,也可以不用這個(gè)插件,得需要自己用protoc.exe生產(chǎn)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>
<mvc:annotation-driven> <mvc:message-converters> <!--看了一下源碼,客戶端請(qǐng)求類型必須設(shè)置成application/x-protobuf采用用這個(gè)類來解析實(shí)體 <bean class="org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter">
</bean> </mvc:message-converters></mvc:annotation-driven>
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; }
@Controllerpublic class ProtobufController{ @RequestMapping(value = "/proto/write1",method= RequestMethod.POST) public ResponseEntity<UserProto.User> protoWrite1(RequestEntity<UserProto.User> requestEntity) { //System.out.println("server===/n"); UserProto.User user = requestEntity.getBody(); System.out.println("server===/n" + user); return ResponseEntity.ok(user); }}
@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();//構(gòu)造 ByteArrayInputStream inputStream = new ByteArrayInputStream(user.toByteArray()); InputStreamEntity inputStreamEntity = new InputStreamEntity(inputStream); //這兩行很重要的,是告訴springmvc客戶端請(qǐng)求和響應(yīng)的類型,指定application/x-protobuf類型,spring會(huì)用ProtobufHttpMessageConverter類來解析請(qǐng)求和響應(yīng)的實(shí)體
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(); } }
當(dāng)時(shí)調(diào)試的時(shí)候試了很多次,響應(yīng)總是被轉(zhuǎn)成xml類型,最后看了源碼才發(fā)現(xiàn)客戶端要設(shè)置httpPost.addHeader("Accept", "application/x-protobuf");其實(shí)也可以自己實(shí)現(xiàn)HttpMessageConverter,也不是很麻煩,本人比較懶,有現(xiàn)成的東西不太愛閉門造車輪。
參考文獻(xiàn):http://jinnianshilongnian.VEvb.com/blog/2107205http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注