前端js与后端java之间的http通信我们一般采用json这种文本格式,实现非常简单,也非常容易被人抓包。protobuf协议起源于google,采用类似TLV(tag,length,value)的编码方式,输出一段字节数组,是一种二进制格式的协议。相比json格式,protobuf编码出来的内容更少,效率更高,传输过程中因为是二进制被人抓包也就更难。protobuf官方给出了很多后端语言(java,C++,python)基于protobuf的交互。前端js与后端的交互例子比较少,因为本身js在处理http请求方面也比较弱。下面提供简单demo:
proto协议文件:
message Req {
required string text = 1;
}
message Resp {
required string code = 1;
}
前端代码:
<!DOCTYPE html>
<html>
<head>
<script src="./long.js"></script>
<script src="./bytebuffer.js"></script>
<script src="./protobuf.js"></script>
<script>
if (typeof dcodeIO === 'undefined' || !dcodeIO.ProtoBuf) {
throw(new Error("ProtoBuf.js is not present. Please see www/index.html for manual setup instructions."));
}
var ProtoBuf = dcodeIO.ProtoBuf;
var proto = ProtoBuf.loadProtoFile("./example.proto");
var Req = proto.build("Req");
var Resp = proto.build("Resp");
var req = new Req();
req.text="1";
var body = new Uint8Array(req.toArrayBuffer());
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8089/xxxxx_getProtoBufReq.action', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) {
var resp=Resp.decode(this.response);
alert(resp.code);
}
};
xhr.send(body);
</script>
</head>
<body>
</body>
</html>
上面的html需要引入long.js,bytebuffer.js,protobuf.js三个文件,都可以在https://github.com/dcodeIO 的网站上找到。
参考资料:
http://mozilla.com.cn/thread-34886-1-1.html
http://web.jobbole.com/83701/
后端java代码:
public String getProtoBuf() {
return "protoBuf";
}
public void getProtoBufReq() {
HttpServletRequest request = ServletActionContext.getRequest();
InputStream input=null;
ByteArrayOutputStream out=null;
ServletOutputStream output=null;
try {
input = request.getInputStream();
out = new ByteArrayOutputStream();
byte by[] = new byte[1024];
int len = 0;
while ((len = input.read(by)) != -1) {
out.write(by, 0, len);
}
Example.Req req=Example.Req.parseFrom(out.toByteArray());
System.out.println(req.getText());
Example.Resp.Builder resp=Example.Resp.newBuilder();
resp.setCode("300");
HttpServletResponse response = ServletActionContext.getResponse();
output=response.getOutputStream();
output.write(resp.build().toByteArray());
} catch (Exception e) {
e.printStackTrace();
}finally{
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(input);
}
}