I write a server(Go)-client(Java) programe, and use protobuf for communication. Define a proto file and share between server and client. In server side:
- compile shared proto file into go by protoc
- serialize the object by proto.Marshal
- send it to client that make a request to its service
In client side:
- compile shared proto file into java by protoc
- get bytes is transferred via http
- deserialize the bytes into object.
Here i get following error:
"com.google.protobuf.InvalidProtocolBufferException: While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length."
I confirmed http work fine and value of bytes received in client side are same to bytes send by server. Do you have same problem on this?
Here is proto file
syntax = "proto3";
package tutorial;
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
In Go server side :
func TodoIndex(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/x-protobuf")
w.WriteHeader(http.StatusOK)
p := &Person{
Id: 1234,
Name: "John Doe",
Email: "jdoe@example.com",
Phones: []*Person_PhoneNumber{
{Number: "555-4321", Type: Person_HOME},
},
}
out, err := proto.Marshal(p)
if err != nil {
panic(err)
}
w.Write(out)
}
In Java client side:
public class MainJavaAndGo {
public static void main(String[] args){
try {
long start = (new Date()).getTime();
System.out.println("begin get");
connect();
System.out.println("end get");
long time = (new Date()).getTime() - start;
}catch(Exception e){
e.printStackTrace();
}
}
public static void connect(){
DefaultBHttpClientConnection connection = new DefaultBHttpClientConnection(8 * 1024);
HttpHost server = hostForString("localhost:8080");
try {
Socket socket = new Socket(server.getHostName(), server.getPort());
connection.bind(socket);
HttpCoreContext writeContext = HttpCoreContext.create();
writeContext.setTargetHost(server);
BasicHttpEntityEnclosingRequest httpRequest = new BasicHttpEntityEnclosingRequest("GET",
"/todos");
HttpProcessor httpproc = makeHttpProcessor();
HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
httpexecutor.preProcess(httpRequest, httpproc, writeContext);
HttpResponse response = httpexecutor.execute(httpRequest, connection, writeContext);
httpexecutor.postProcess(response, httpproc, writeContext);
InputStream inputStream = response.getEntity().getContent();
byte[] data = IOUtils.toByteArray(inputStream);
Addressbook.AddressBook addressBook = Addressbook.AddressBook.parseFrom(data);
int foo = 0;
foo++;
}catch(Exception e){
e.printStackTrace();
try {
connection.shutdown();
}catch (Exception ioe){
ioe.printStackTrace();
}
}
}
public static HttpHost hostForString(String hostStr) {
String[] host = hostStr.split(":", 2);
HttpHost httphost = new HttpHost(host[0], Integer.parseInt(host[1]));
return httphost;
}
public static HttpProcessor makeHttpProcessor() {
return HttpProcessorBuilder.create().add(new RequestContent()).add(new RequestTargetHost())
.add(new RequestConnControl()).add(new RequestUserAgent("Test Protobuf/1.1"))
.add(new RequestExpectContinue(true)).build();
}
}
I got InvalidProtocolBufferException
com.google.protobuf.InvalidProtocolBufferException: While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length.
at com.google.protobuf.InvalidProtocolBufferException.truncatedMessage(InvalidProtocolBufferException.java:82)
at com.google.protobuf.CodedInputStream$ArrayDecoder.skipRawBytes(CodedInputStream.java:1200)
at com.google.protobuf.CodedInputStream$ArrayDecoder.skipField(CodedInputStream.java:578)
at com.auth0.protobuf.Addressbook$Person.<init>(Addressbook.java:112)
at com.auth0.protobuf.Addressbook$Person.<init>(Addressbook.java:77)
at com.auth0.protobuf.Addressbook$Person$1.parsePartialFrom(Addressbook.java:1817)
at com.auth0.protobuf.Addressbook$Person$1.parsePartialFrom(Addressbook.java:1812)
at com.google.protobuf.CodedInputStream$ArrayDecoder.readMessage(CodedInputStream.java:816)
at com.auth0.protobuf.Addressbook$AddressBook.<init>(Addressbook.java:1914)
at com.auth0.protobuf.Addressbook$AddressBook.<init>(Addressbook.java:1871)
at com.auth0.protobuf.Addressbook$AddressBook$1.parsePartialFrom(Addressbook.java:2571)
at com.auth0.protobuf.Addressbook$AddressBook$1.parsePartialFrom(Addressbook.java:2566)
at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:163)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:197)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:209)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:214)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49)
at com.auth0.protobuf.Addressbook$AddressBook.parseFrom(Addressbook.java:2065)
at com.auth0.MainJavaAndGo.connect(MainJavaAndGo.java:78)
at com.auth0.MainJavaAndGo.main(MainJavaAndGo.java:35)