我使用的是Maven Project,所以
1。第一步加入Maven Dependency。
<dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>2.4.1</version> </dependency>
2。 然后,加入ant plugin来帮助我们产生protobuf 的java bean。
<build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <mkdir dir='target/generated-sources' /> <exec executable='protoc'> <arg value='--java_out=target/generated-sources' /> <arg value='src/main/resources/addressbook.proto' /> </exec> </tasks> <sourceRoot>target/generated-sources</sourceRoot> </configuration> </execution> </executions> </plugin> </plugins> <pluginManagement> <plugins> <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-antrun-plugin </artifactId> <versionRange>[1.3,)</versionRange> <goals> <goal>run</goal> </goals> </pluginExecutionFilter> <action> <ignore></ignore> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> </build>
3。 创建addressbook.proto文件
package tutorial; option java_package = "com.sampullara.jaxrsprotobuf.tutorial"; option java_outer_classname = "AddressBookProtos"; message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1; }
4。 运行mvn generate-sources命令来生成AddressBookProtos.java文件。
5。创建rest server端代码AddressBookService.java
package com.sampullara; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import com.sampullara.jaxrsprotobuf.tutorial.AddressBookProtos; @Path("/person") public class AddressBookService { @GET @Produces("application/x-protobuf") public AddressBookProtos.Person getPerson() { return AddressBookProtos.Person.newBuilder() .setId(1) .setName("Sam") .setEmail("sam@sampullara.com") .addPhone(AddressBookProtos.Person.PhoneNumber.newBuilder() .setNumber("415-555-1212") .setType(AddressBookProtos.Person.PhoneType.MOBILE) .build()) .build(); } @POST @Consumes("application/x-protobuf") @Produces("application/x-protobuf") public AddressBookProtos.Person reflect(AddressBookProtos.Person person) { return person; } }
6。创建ProtobufProviders.java文件处理protobuf对象序列化。
package com.sampullara; import com.google.protobuf.GeneratedMessage; import com.google.protobuf.Message; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Map; import java.util.WeakHashMap; /** * These providers implement the conversion of protobuf objects to and from their serialized form over the wire. * * User: sam * Date: Dec 27, 2008 * Time: 3:13:17 PM */ public class ProtobufProviders { @Provider @Consumes("application/x-protobuf") public static class ProtobufMessageBodyReader implements MessageBodyReader<Message> { public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return Message.class.isAssignableFrom(type); } public Message readFrom(Class<Message> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { try { Method newBuilder = type.getMethod("newBuilder"); GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(type); return builder.mergeFrom(entityStream).build(); } catch (Exception e) { throw new WebApplicationException(e); } } } @Provider @Produces("application/x-protobuf") public static class ProtobufMessageBodyWriter implements MessageBodyWriter<Message> { public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return Message.class.isAssignableFrom(type); } private Map<Object, byte[]> buffer = new WeakHashMap<Object, byte[]>(); public long getSize(Message m, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { m.writeTo(baos); } catch (IOException e) { return -1; } byte[] bytes = baos.toByteArray(); buffer.put(m, bytes); return bytes.length; } public void writeTo(Message m, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { entityStream.write(buffer.remove(m)); } } }
7。创建服务器
package com.sampullara; import java.io.IOException; import java.net.URI; import javax.ws.rs.core.UriBuilder; import com.sun.net.httpserver.HttpServer; import com.sun.jersey.api.container.httpserver.HttpServerFactory; import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; public class Main { public static final URI BASE_URI = UriBuilder.fromUri("http://localhost/").port(9998).build(); public static HttpServer createServer(URI uri) throws IOException { ResourceConfig rc = new PackagesResourceConfig("com.sampullara"); return HttpServerFactory.create(uri, rc); } }
8。编写客户端代码
package com.sampullara; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import junit.framework.TestCase; import com.sampullara.ProtobufProviders.ProtobufMessageBodyReader; import com.sampullara.ProtobufProviders.ProtobufMessageBodyWriter; import com.sampullara.jaxrsprotobuf.tutorial.AddressBookProtos; //import com.sun.grizzly.http.SelectorThread; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.net.httpserver.HttpServer; /** * TODO: Edit this * <p/> * User: sam * Date: Dec 27, 2008 * Time: 5:10:58 PM */ public class MainTest extends TestCase { private HttpServer server; private WebResource r; @Override protected void setUp() throws Exception { super.setUp(); //start the Grizzly web container and create the client server = Main.createServer(Main.BASE_URI); server.start(); ClientConfig cc = new DefaultClientConfig(); cc.getClasses().add(ProtobufMessageBodyReader.class); cc.getClasses().add(ProtobufMessageBodyWriter.class); Client c = Client.create(cc); r = c.resource(Main.BASE_URI); } @Override protected void tearDown() throws Exception { super.tearDown(); server.stop(0); } public void testUsingJerseyClient() { WebResource wr = r.path("person"); AddressBookProtos.Person p = null; try { p = wr.get(AddressBookProtos.Person.class); } catch (UniformInterfaceException e) { e.printStackTrace(); } assertEquals("Sam", p.getName()); AddressBookProtos.Person p2 = wr.type("application/x-protobuf").post(AddressBookProtos.Person.class, p); assertEquals(p, p2); } public void testUsingURLConnection() throws IOException { AddressBookProtos.Person person; { URL url = new URL("http://localhost:9998/person"); URLConnection urlc = url.openConnection(); urlc.setDoInput(true); urlc.setRequestProperty("Accept", "application/x-protobuf"); person = AddressBookProtos.Person.newBuilder().mergeFrom(urlc.getInputStream()).build(); assertEquals("Sam", person.getName()); } { URL url = new URL("http://localhost:9998/person"); HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); urlc.setDoInput(true); urlc.setDoOutput(true); urlc.setRequestMethod("POST"); urlc.setRequestProperty("Accept", "application/x-protobuf"); urlc.setRequestProperty("Content-Type", "application/x-protobuf"); person.writeTo(urlc.getOutputStream()); AddressBookProtos.Person person2 = AddressBookProtos.Person.newBuilder().mergeFrom(urlc.getInputStream()).build(); assertEquals(person, person2); } } }
相关推荐
这是一个典型的企业级应用开发场景,其中Spring提供了强大的依赖注入和AOP(面向切面编程)功能,Jersey作为JAX-RS(Java API for RESTful Web Services)的实现,负责处理HTTP请求和响应,而Protobuf则是一种高效的...
Protobuf是一套类似Json或者XML的数据传输格式和规范,用于不同应用或进程之间进行通信时使用。通信时所传递的信息是通过Protobuf定义的message数据结构进行打包,然后编译成二进制的码流再进行传输或者存储。本次...
protobuf编译好的文件通常指的是Google开源的Protocol Buffers(简称protobuf)编译后的二进制库、头文件和源代码,这些文件已经过编译,可以直接在开发项目中使用,以实现数据序列化和反序列化的高效通信。protobuf...
在IT行业中,数据序列化和反序列化是一个关键任务,特别是在网络通信、数据存储和跨平台数据交换中。Google推出的Protocol Buffers...通过理解和应用这些技术,你可以优化你的应用程序,提高数据传输的效率和兼容性。
标题中的“protobuf jar 和 protoc 3.6.0”指的是Google开源的Protocol Buffers(简称protobuf)在3.6.0版本的Java实现库(protobuf-java-3.6.0.jar)和编译器(protoc-3.6.0)。Protocol Buffers是一种高效的数据...
protobuf,全称Protocol Buffers,是Google开发的一种...通过学习和使用protobuf,开发者可以提升应用程序的效率,优化数据传输,降低系统复杂性。对于任何涉及大量数据交换的项目,protobuf都是一个值得考虑的选择。
它通过定义消息格式,将数据结构转换为二进制流,相比XML或JSON等文本格式,protobuf在传输和存储时具有更高的效率和更小的体积。protobuf不仅支持C++、Java和Python,还有丰富的语言扩展,如Go、JavaScript、PHP等...
3. **生成源代码**:protoc会生成对应语言的源代码,通常包括一个或多个类,这些类提供了序列化和反序列化protobuf消息的功能。 4. **集成到项目**:将生成的源代码添加到项目中,然后就可以像使用普通类一样使用...
protobuf序列化和反序列化技术是大数据处理领域中不可或缺的一部分,尤其在实时大数据场景下,高效的数据传输和存储对性能有着直接影响。谷歌推出的Protocol Buffers(简称protobuf)是一种语言无关、平台无关的数据...
在IT行业中,Unity3D是一款广泛应用于游戏开发的跨平台引擎,它支持创建2D、3D、VR和AR等多种类型的游戏。Protobuf(Protocol Buffers)是Google开发的一种数据序列化协议,常用于高效地存储和传输结构化数据。...
3. 对于特定的开发环境和应用场景,3.5.0可能是一个稳定且广泛使用的版本。 在使用 **protobuf-3.5.0** 源码时,开发者通常会进行以下步骤: 1. 解压 `protobuf-3.5.0` 压缩包。 2. 配置构建环境,这可能涉及设置...
在Android开发中,gRPC和Protocol Buffers(protobuf)是两个强大的工具,它们可以极大地提升应用的性能和可维护性。本教程将详细介绍如何在Android Studio的Kotlin环境中使用gRPC和protobuf进行通信。 gRPC是一个...
ROS2 (Robot Operating System 2) 是一个开源操作系统,用于构建智能机器人系统和自动化应用。在ROS2中,数据通信是通过DDS(Data Distribution Service)实现的,它是一种标准的实时中间件,用于高效率、可靠的...
在实际应用中,protobuf广泛应用于RPC(远程过程调用)框架、数据库存储、配置文件和日志记录等领域。例如,Google的gRPC框架就是基于protobuf来定义服务接口和交换数据的。 总的来说,protobuf2.6.1提供了在...
6. **编写服务端代码**:创建一个Spring Boot REST控制器,使用protobuf生成的Java类处理请求和响应。例如,你可以创建一个`PersonController`,处理HTTP请求并将数据转化为protobuf格式。 7. **客户端调用**:...
3. **数据持久化**:除了网络通信,Java 应用也可以使用 Protobuf 存储结构化数据到文件或数据库,便于数据交换和迁移。 **四、protobuf 标签** 在 Protobuf 中,每个字段都有一个唯一的整数标签(Tag),用来标识...
Protocol Buffers允许开发者定义数据结构的模式(schema),然后生成相应的语言绑定(如C++、Java、Python),使得应用程序可以方便地存储、读取和交换结构化数据。这种序列化格式比XML更紧凑,比JSON更快,且易于...
在Windows环境下,使用Visual Studio 2015进行protobuf的静态编译是一项关键任务,因为静态编译可以将protobuf库与应用程序链接在一起,形成一个单一的可执行文件,避免了运行时对动态库的依赖,提高了部署的便利性...
protoc是protobuf的核心工具,它负责将.proto定义文件转换为各种目标语言(如C++、Java、Python等)的源代码,使得应用程序能够方便地序列化和反序列化protobuf消息。 标签 "protobuf" 和 "protoc" 是与该主题直接...
通过运行这些示例,开发者可以更好地理解和掌握protobuf在JAVA环境中的实际应用。 ### 5. 进阶使用 - **服务端RPC**:protobuf也支持gRPC,一种基于HTTP/2的高性能RPC框架,可用于构建分布式微服务架构。 - **字段...