使用协议缓冲区的 Android Http 请求和响应
Posted
技术标签:
【中文标题】使用协议缓冲区的 Android Http 请求和响应【英文标题】:Android Http request and response using protocol buffer 【发布时间】:2013-11-18 11:47:25 【问题描述】:我是 protocol buffer 主题的新手。 但我知道 json 解析等等 现在我实际上正在研究这个协议缓冲区,我正在制作一个应用程序,它使用带有协议缓冲区的 android 进行 Http 请求和响应。
我正在使用 android 中的协议缓冲区制作一个登录页面。
服务的一切都在工作中返回我想要的每个字段的响应,但是 服务给我的信息与实际来自服务器的响应不同。
我对 .proto 文件的协议缓冲区和从 proto 编译 java 文件的工具有基本的了解,所有的连接也完成了,我只需要响应或如何序列化和反序列化响应消息。
**AuthenticateUserRequest.Builder abr = AuthenticateUserRequest
.newBuilder();
abr.setUserID(p_UserName);
abr.setPassword(p_Password);
URL url = new URL(
"http://10.0.2.2:49847/Services");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// ResCode = conn.getResponseCode();
// URLConnection conn = url.openConnection();
conn.setRequestProperty("content-type", "application/x-protobuf");
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
abr.build().writeTo(os);
os.flush();
os.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
sb.append(line);
byte[] result = String.valueOf(sb).getBytes();
AuthenticateUserResponse.parseFrom(result).toBuilder();**
这是我的任何人的代码都可以帮助我解决这个问题。
提前致谢。
【问题讨论】:
【参考方案1】:您的问题是您试图将编码的 protobuf 响应视为文本。 Protocol Buffers 是一种二进制序列化格式。如果将二进制数据转换为String
,或者尝试使用Reader
读取,则会损坏。
要解决此问题,请将代码的整个第二部分(从您创建 BufferedReader
的行开始)替换为:
AuthenticateUserResponse response =
AuthenticateUserResponse.parseFrom(conn.getInputStream());
【讨论】:
嘿,Kenton Varda,这简直太棒了,它的工作原理非常感谢,,非常感谢......非常好......谢谢伙计,, 你好 Kenton,你能帮我做这件事吗***.com/q/38670400/4140857【参考方案2】:我不知道这是否能回答你的问题,但这是我的代码。
我用过这两个类。
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
public class HttpClientSingleton
private static final int JSON_CONNECTION_TIMEOUT = 30000;
private static final int JSON_SOCKET_TIMEOUT = 50000;
private static HttpClientSingleton instance;
private HttpParams httpParameters ;
private DefaultHttpClient httpclient;
private void setTimeOut(HttpParams params)
HttpConnectionParams.setConnectionTimeout(params, JSON_CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, JSON_SOCKET_TIMEOUT);
private HttpClientSingleton()
httpParameters = new BasicHttpParams();
setTimeOut(httpParameters);
httpclient = new DefaultHttpClient(httpParameters);
public static DefaultHttpClient getHttpClientInstace()
if(instance==null)
instance = new HttpClientSingleton();
return instance.httpclient;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import android.util.Log;
public class WSClient
public final String get(String url)
String resultCode = "";
String result = "";
HttpGet httpget = new HttpGet(url);
HttpResponse response;
try
Log.i("WSClient Get taxi", "Url -> " + url);
response = HttpClientSingleton.getHttpClientInstace().execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null)
//Código da respostas
resultCode = String.valueOf(response.getStatusLine().getStatusCode());
InputStream instream = entity.getContent();
//Resposta
result = toString(instream);
instream.close();
Log.i("WSClient if entity not null taxi", "Result Code " + resultCode);
Log.i("WSClient if entity not null taxi", "Result: " + result);
if(!resultCode.equals("200"))
result = "\"errorCode\": 1, \"descricao\": \"Falha de rede!\"";
catch (Exception e)
Log.i("Exception WSClient get taxi", "Exception ->" + e);
result = "\"errorCode\": 1, \"descricao\": \"Falha de rede!\"";
return result;
public final String post(String url, String json)
String resultCode = "";
String result = "";
try
HttpPost httpPost = new HttpPost(new URI(url));
httpPost.setHeader("Content-type", "application/json");
StringEntity sEntity = new StringEntity(json, "UTF-8");
httpPost.setEntity(sEntity);
HttpResponse response;
response = HttpClientSingleton.getHttpClientInstace().execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null)
resultCode = String.valueOf(response.getStatusLine().getStatusCode());
InputStream instream = entity.getContent();
result = toString(instream);
instream.close();
if(!resultCode.equals("200"))
result = "\"errorCode\": 1, \"descricao\": \"Falha de rede!\"";
catch (Exception e)
result = "\"errorCode\": 1, \"descricao\": \"Falha de rede!\"";
return result;
public final String put(String url, String json)
String resultCode = "";
String result = "";
try
HttpPut httput = new HttpPut(url);
httput.setHeader("Content-type", "application/json");
StringEntity sEntity = new StringEntity(json, "UTF-8");
httput.setEntity(sEntity);
HttpResponse response;
response = HttpClientSingleton.getHttpClientInstace().execute(httput);
HttpEntity entity = response.getEntity();
if (entity != null)
resultCode = String.valueOf(response.getStatusLine().getStatusCode());
InputStream instream = entity.getContent();
result = toString(instream);
instream.close();
if(!resultCode.equals("200"))
result = "\"errorCode\": 1, \"descricao\": \"Falha de rede!\"";
catch (Exception e)
result = "\"errorCode\": 1, \"descricao\": \"Falha de rede!\"";
return result;
private String toString(InputStream is) throws IOException
byte[] bytes = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int lidos;
while ((lidos = is.read(bytes)) > 0)
baos.write(bytes, 0, lidos);
return new String(baos.toByteArray());
【讨论】:
感谢此代码非常棒,但正如我在问题中提到的,我知道如何使用 json 进行连接,我希望这一切都在协议缓冲区中。 developers.google.com/protocol-buffers/docs/overview看这个链接以上是关于使用协议缓冲区的 Android Http 请求和响应的主要内容,如果未能解决你的问题,请参考以下文章
Android客户端采用Http 协议Post方式请求与服务端进行数据交互