以下是消息模式:>
message ServerResponse {
optional string ReferenceCode = 1;
optional NestedMessageProto.NestedMessage NestedMessage = 2;//Huge size data in response
optional bool Success = 3 [default = false];
repeated Errors Errors = 4;
}
下面是从serve获取响应并调用proto-response方法的代码。
String apiResponse = Server Response
protoResponseClass.parseFrom(apiResponse.getBytes())
its failing when reading the NestedMessage response on below bold line
public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
if (byteLimit < 0) {
throw InvalidProtocolBufferException.negativeSize();
}
byteLimit += totalBytesRetired + bufferPos;
if (byteLimit > currentLimit) {
currentLimit = byteLimit + currentLimit;
}
final int oldLimit = currentLimit;
**if (byteLimit > oldLimit) {
throw InvalidProtocolBufferException.truncatedMessage();
}**
currentLimit = byteLimit;
recomputeBufferSizeAfterLimit();
return oldLimit;
}
当它读取嵌套消息时,字节限制变得大于旧限制。解决方案是什么?
感谢
这几乎可以肯定是问题所在:
String apiResponse = Server Response
protoResponseClass.parseFrom(apiResponse.getBytes())
协议缓冲区消息是二进制数据。它们不是文本,不应该作为文本处理。您从服务器获取二进制响应,以某种方式将其解释为文本(我们不知道如何),然后使用平台默认编码将其转换回字节数组(这几乎总是一个坏主意-永远不要在不指定字符集的情况下调用getBytes()
,即使调用getBytes()
是合适的,但它不在这里)。转换为文本和返回几乎肯定会丢失信息——很可能会使解析代码期望得到比消息中实际存在的更多的数据。
您应该从一开始就将服务器响应作为二进制数据处理——理想情况下,只需将服务器响应中的InputStream
传递到parseFrom
,但至少将其作为字节数组而不是String
读取。
直接使用EntityUtils.toByteArray,而不是将httpresponse转换为字符串,然后转换为字节数组进行解析。
private String readResponse(HttpResponse httpresponse) throws IOException {
int responseCode = httpresponse.getStatusLine().getStatusCode();
String mimeType = httpresponse.getFirstHeader(CONTENT_TYPE_KEY).getValue();
if (responseCode != HttpURLConnection.HTTP_OK) {
String cause = String.format("Bad HTTP response code: %dnOr MIME type: %s", responseCode, mimeType);
throw new IOException(cause);
}
return EntityUtils.toString(httpresponse.getEntity());
}