使用protobuf作为http通讯格式
·
protobuf谷歌的开源序列化项目,类似的还有于json,xml等组织格式;据说protobuf的序列化占用的数据量最下,传输效率最高,并且作为服务器开发者,只需要掌握.proto文件的书写方式,就可以生成不同语言的序列化对象。这次讲解一下如何在服务器和安卓客户端之间利用protobuf传输数据。
测试的接口是登录功能:我写的proto文件如下:
syntax = "proto2";
message LoginUser{
optional string name=1[default=""];
optional string pass=2[default=""];
optional int32 sex=3[default=0];
}
在ubuntu中,利用protoc 命令生成相关的java文件,然后复制到相应的目录中,这份java文件androud端和服务器端可以共用一份;
然后服务器端的测试接口如下:
public class LoginServer extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletHelp.set(req, resp);
InputStream stream=req.getInputStream();
LoginUser user=LoginUser.parseFrom(stream);
if(user!=null){
System.out.print(user.toString());
LoginMsg msg=LoginMsg.newBuilder().setCode(200).setMsg("成功").build();
resp.getOutputStream().write(msg.toByteArray());
}
}
}
然后启动服务等待链接,android端的代码如下:
AsynTool.getInstance().submit(new Runnable() {
@Override
public void run() {
String loginname = name.getText().toString();
String loginpass = pass.getText().toString();
LoginUserOuterClass.LoginUser.Builder builder= LoginUserOuterClass.LoginUser.newBuilder();
builder.setName(loginname);
builder.setPass(loginpass);
LoginUserOuterClass.LoginUser user=builder.build();
try {
new HttpClient().post(SerAddUtils.getLogin(), user.toByteArray(), new HttpStreamCallback() {
@Override
public void getResult(InputStream stream) {
try {
final LoginMsgOuterClass.LoginMsg msg= LoginMsgOuterClass.LoginMsg.parseFrom(stream);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(LoginActivity.this,msg.toString(),Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
public void post(String url,byte[] postdata,HttpStreamCallback callBack) throws Exception{
URL url1 = new URL(url);
httpURLConnection = (HttpURLConnection) url1.openConnection();
httpURLConnection.setRequestMethod("POST");
if(HttpCookie.getInstance().get().getCookies()!=null&&HttpCookie.getInstance().get().getCookies().size()>0){
httpURLConnection.setRequestProperty("Cookie","JSESSIONID="+HttpCookie.getInstance().get().getCookies().get(0).getValue());
}
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setConnectTimeout(3000);
BufferedOutputStream outputStream=new BufferedOutputStream(httpURLConnection.getOutputStream());
outputStream.write(postdata);
outputStream.flush();
httpURLConnection.connect();
if(httpURLConnection.getResponseCode()==200){
Map<String, List<String>> head = httpURLConnection.getHeaderFields();
InputStream stream = httpURLConnection.getInputStream();
callBack.getResult(stream);
}
}
然后客户端进行测试:
测试结果如下:
如果客户端输入汉字,那么会会自动转换成utf-8编码,如果是英文或者数字,就不会;
如下客户端输入:
82727272 你好
服务端接收如下:
name: “82727272”
pass: “\344\275\240\345\245\275”
客户端输入:
82727272 abc
服务器接收:
name: “82727272”
pass: “abc”
感觉用这个很方便们可以省去对字段进行编码吗;并且protobuf可以判断字符是否是utf-8编码。因此在解码具体字段值的时候也很方便;不需要我们自己去定义数据结构;
更多推荐
已为社区贡献1条内容
所有评论(0)