Protostuff开发
作者:chszs,未经博主允许不得转载。
五、Protostuff用法
1、为Java实体产生schemas
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.3.8</version>
</dependency>
2、Runtime schemas
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.3.8</version>
</dependency>
3、Protostuff的Maven插件
Protostuff的Maven插件可以从.proto文件中生成Java源码或其它语言的源码——通过使用基于StringTemplate的代码生成器(或扩展)。
下面讲述此插件的用法。
1)项目的结构如下:
<project root>
├───pom.xml
└───src
└───main
└───proto
└───hello.proto
Protocol buffer定义路径是可配置的,但是推荐使用src/main/proto/路径。所有的.proto文件及其子目录都放于此目录下,且会被protobuf定义视为包结构,以import方式导入。
hello.proto的内容如下:
package search;
option java_package = "stuff.ch";
message HelloRequest {
optional string name = 1;
}
message HelloResponse {
optional string greeting = 1;
}
service HelloService {
rpc hello (HelloRequest) returns (HelloResponse);
}
执行命令:
mvn protostuff:compile
在项目目录下产生相应的Java文件。
<project root>
├───pom.xml
└───target
└───generated-sources
└───proto
└───stuff
└───ch
└───HelloRequest.java
└───HelloResponse.java
HelloRequest.java的内容如下:
// Generated by http://code.google.com/p/protostuff/ ... DO NOT EDIT!
// Generated from proto
package stuff.ch;
import javax.annotation.Generated;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Objects;
import io.protostuff.GraphIOUtil;
import io.protostuff.Input;
import io.protostuff.Message;
import io.protostuff.Output;
import io.protostuff.Schema;
@Generated("java_bean")
public final class HelloRequest implements Externalizable, Message<HelloRequest>, Schema<HelloRequest> {
public static Schema<HelloRequest> getSchema() {
return DEFAULT_INSTANCE;
}
public static HelloRequest getDefaultInstance() {
return DEFAULT_INSTANCE;
}
static final HelloRequest DEFAULT_INSTANCE = new HelloRequest();
private String name;
public HelloRequest() {
}
// getters and setters
// name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || this.getClass() != obj.getClass()) {
return false;
}
final HelloRequest that = (HelloRequest) obj;
return Objects.equals(this.name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public String toString() {
return "HelloRequest{" + "name=" + name + '}';
}
// java serialization
public void readExternal(ObjectInput in) throws IOException {
GraphIOUtil.mergeDelimitedFrom(in, this, this);
}
public void writeExternal(ObjectOutput out) throws IOException {
GraphIOUtil.writeDelimitedTo(out, this, this);
}
// message method
public Schema<HelloRequest> cachedSchema() {
return DEFAULT_INSTANCE;
}
// schema methods
public HelloRequest newMessage() {
return new HelloRequest();
}
public Class<HelloRequest> typeClass() {
return HelloRequest.class;
}
public String messageName() {
return HelloRequest.class.getSimpleName();
}
public String messageFullName() {
return HelloRequest.class.getName();
}
public boolean isInitialized(HelloRequest message) {
return true;
}
public void mergeFrom(Input input, HelloRequest message) throws IOException {
for (int number = input.readFieldNumber(this);; number = input.readFieldNumber(this)) {
switch (number) {
case 0:
return;
case 1:
message.name = input.readString();
break;
default:
input.handleUnknownField(number, this);
}
}
}
public void writeTo(Output output, HelloRequest message) throws IOException {
if (message.name != null)
output.writeString(1, message.name, false);
}
public String getFieldName(int number) {
return Integer.toString(number);
}
public int getFieldNumber(String name) {
return Integer.parseInt(name);
}
}
HelloResponse.java的内容如下:
// Generated by http://code.google.com/p/protostuff/ ... DO NOT EDIT!
// Generated from proto
package stuff.ch;
import javax.annotation.Generated;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Objects;
import io.protostuff.GraphIOUtil;
import io.protostuff.Input;
import io.protostuff.Message;
import io.protostuff.Output;
import io.protostuff.Schema;
@Generated("java_bean")
public final class HelloResponse implements Externalizable, Message<HelloResponse>, Schema<HelloResponse> {
public static Schema<HelloResponse> getSchema() {
return DEFAULT_INSTANCE;
}
public static HelloResponse getDefaultInstance() {
return DEFAULT_INSTANCE;
}
static final HelloResponse DEFAULT_INSTANCE = new HelloResponse();
private String greeting;
public HelloResponse() {
}
// getters and setters
// greeting
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || this.getClass() != obj.getClass()) {
return false;
}
final HelloResponse that = (HelloResponse) obj;
return Objects.equals(this.greeting, that.greeting);
}
@Override
public int hashCode() {
return Objects.hash(greeting);
}
@Override
public String toString() {
return "HelloResponse{" + "greeting=" + greeting + '}';
}
// java serialization
public void readExternal(ObjectInput in) throws IOException {
GraphIOUtil.mergeDelimitedFrom(in, this, this);
}
public void writeExternal(ObjectOutput out) throws IOException {
GraphIOUtil.writeDelimitedTo(out, this, this);
}
// message method
public Schema<HelloResponse> cachedSchema() {
return DEFAULT_INSTANCE;
}
// schema methods
public HelloResponse newMessage() {
return new HelloResponse();
}
public Class<HelloResponse> typeClass() {
return HelloResponse.class;
}
public String messageName() {
return HelloResponse.class.getSimpleName();
}
public String messageFullName() {
return HelloResponse.class.getName();
}
public boolean isInitialized(HelloResponse message) {
return true;
}
public void mergeFrom(Input input, HelloResponse message) throws IOException {
for (int number = input.readFieldNumber(this);; number = input.readFieldNumber(this)) {
switch (number) {
case 0:
return;
case 1:
message.greeting = input.readString();
break;
default:
input.handleUnknownField(number, this);
}
}
}
public void writeTo(Output output, HelloResponse message) throws IOException {
if (message.greeting != null)
output.writeString(1, message.greeting, false);
}
public String getFieldName(int number) {
return Integer.toString(number);
}
public int getFieldNumber(String name) {
return Integer.parseInt(name);
}
}
编写HelloService.java,内容如下:
package stuff.ch;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.Schema;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class HelloService {
public static final Schema<HelloRequest> SEARCH_REQUEST_SCHEMA = HelloRequest.getSchema();
public static final Schema<HelloResponse> SEARCH_RESPONSE_SCHEMA = HelloResponse.getSchema();
/**
* Sample "hello" rpc method handler.
*
* @param requestData
* {@code HelloRequest} binary array encoded using Protocol
* Buffers
* @return {@code HelloResponse} binary array encoded using Protocol Buffers
*/
public byte[] hello(byte[] requestData) throws IOException {
HelloRequest request = deserialize(requestData);
HelloResponse response = hello(request);
return serialize(response);
}
private byte[] serialize(HelloResponse response) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
LinkedBuffer buffer = LinkedBuffer.allocate();
ProtobufIOUtil.writeTo(outputStream, response, SEARCH_RESPONSE_SCHEMA, buffer);
return outputStream.toByteArray();
}
private HelloRequest deserialize(byte[] requestData) {
HelloRequest request = SEARCH_REQUEST_SCHEMA.newMessage();
ProtobufIOUtil.mergeFrom(requestData, request, SEARCH_REQUEST_SCHEMA);
return request;
}
/**
* Service method implementation.
*/
private HelloResponse hello(HelloRequest request) {
HelloResponse response = new HelloResponse();
String name = request.getName();
response.setGreeting("Hello, " + name);
return response;
}
}
编写单元测试类HelloServiceTest.java,内容如下:
package stuff.ch;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class HelloServiceTest {
public static final byte[] REQUEST = new byte[] { 0x0A, 0x03, '4', '2', '!' };
public static final byte[] RESPONSE = new byte[] { 0x0A, 0x0A, 'H', 'e', 'l', 'l', 'o', ',', ' ', '4', '2', '!' };
private HelloService service;
@Before
public void setUp() throws Exception {
service = new HelloService();
}
@Test
public void testSearch() throws Exception {
byte[] responseData = service.hello(REQUEST);
Assert.assertArrayEquals(RESPONSE, responseData);
}
}
运行单元测试,测试通过。