使用协议缓冲区的 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 请求和响应的主要内容,如果未能解决你的问题,请参考以下文章

Http与Android网络请求的几种协议

Android客户端采用Http 协议Post方式请求与服务端进行数据交互

Android攻城狮 http协议

Android实战之旅 006Android中的HTTP通信

传输层协议 ——— UDP协议

Android 网络请求详解