1、json字符串和pb对象之间的转换:
1)pom.xml
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.2</version>
</dependency>
2)pb消息定义:
option java_package = "com.abc.proto";
option java_outer_classname="HelloWordPB";
message HelloWord {
optional int64 id = 1;
optional string name = 2;
repeated string recId = 3;
}
3)java代码:
public class PBTest {
public static void main(String[] args) {
JSONObject jo = new JSONObject();
JSONArray ja = new JSONArray();
ja.add("1");
ja.add("2");
jo.put("id", 123456);//这里不能是字符串类型,否则pb会报错
jo.put("name", "test");
jo.put("recId", ja);
String jsonStr = jo.toJSONString();
System.out.println(jsonStr);
//json > pb
Builder newBuilder = HelloWordPB.HelloWord.newBuilder();
try {
JsonFormat.merge(jsonStr, newBuilder);
System.out.println(newBuilder.build().toString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//pb > json
String printToString = JsonFormat.printToString(newBuilder.build());
System.out.println(printToString);
}
}
输出:
{"name":"test","id":123456,"recId":["1","2"]}
id: 123456
name: "test"
recId: "1"
recId: "2"
{"id": 123456,"name": "test","recId": ["1","2"]}
2、toString于pb对象之间转换:
public static void main(String...strings) {
Builder newBuilder = ApiLogPB.ApiLog.newBuilder();
newBuilder.setCost(10);
newBuilder.setChId("default");
newBuilder.setReqId("reqid");
newBuilder.setFNum(12);
newBuilder.setPuid("puid");
newBuilder.setUId("uid");
ApiLog apiLog = newBuilder.build();
String string = apiLog.toString();
System.out.println(string);
System.out.println("--------------------------");
Builder newBuilder2 = ApiLogPB.ApiLog.newBuilder();
try {
TextFormat.merge(string, newBuilder2);
} catch (ParseException e) {
e.printStackTrace();
}
String chId = newBuilder2.getChId();
System.out.println(chId);
}
输出:
puid: "puid"
uId: "uid"
reqId: "reqid"
fNum: 12
cost: 10
chId: "default"
--------------------------
default
3、从文件中构建pb对象:
1)pb结构
option java_package="com.lanjingling.cinema";
enum MovieType{
CHILDREN=1;
ADULT=2;
NORMAL=3;
OHTER=4;
}
message Movie{
required string name=1;
required MovieType type=2;
optional int32 releaseTimeStamp=3;
optional string description=4;
}
message Ticket{
required int32 id=1;
repeated Movie movie=2;
optional Customer customer=3;
}
2)构建pb对象,tostring输出到文件:
public class Test {
public static void main(String[] args) throws Exception {
Cinema.Movie.Builder movieBuilder = Cinema.Movie.newBuilder();
movieBuilder.setName("The Shining");
movieBuilder.setType(Cinema.MovieType.ADULT);
movieBuilder.setReleaseTimeStamp(327859200);
Movie movie = movieBuilder.build();
Cinema.Movie.Builder movieBuilder1 = Cinema.Movie.newBuilder();
movieBuilder1.setName("The Shining1");
movieBuilder1.setType(Cinema.MovieType.CHILDREN);
movieBuilder1.setReleaseTimeStamp(327859201);
Movie movie1 = movieBuilder1.build();
Cinema.Ticket.Builder ticketBuilder = Cinema.Ticket.newBuilder();
ticketBuilder.setId(1);
ticketBuilder.addMovie(movie);
ticketBuilder.addMovie(movie1);
Ticket ticket = ticketBuilder.build();
System.out.println(ticket.toString());
}
}
将输出保存到cineme.txt文件。内容如下:
id: 1
movie {
name: "The Shining"
type: ADULT
releaseTimeStamp: 327859200
}
movie {
name: "The Shining1"
type: CHILDREN
releaseTimeStamp: 327859201
}
3)从文件中读取数据,反序列化:
public class Test2 {
public static void main(String[] args) throws Exception {
Cinema.Ticket.Builder ticketBuilder = Cinema.Ticket.newBuilder();
InputStream inputStream = new FileInputStream("D://cinema.txt");
TextFormat.merge(new InputStreamReader(inputStream), ticketBuilder);
Ticket ticket = ticketBuilder.build();
System.out.println(ticket);
}
}
4、pb在构造Builder的时候可以传入一个pb对象:
1)假设我们从redis中读取了一个pb二进制数据,然后反序列化成pb对象:
com.abc.proto.UserRecHistoryPB.UserRecHistory userRecHistory = null;
String KEY = MessageFormat.format(CacheConstants.CACHE_KEY_USER_HISTORY_PERF, deviceId);
byte[] bs = couchbaseHistoryDao.get(KEY);
if (bs != null) {
userRecHistory = UserRecHistoryPB.UserRecHistory.parseFrom(bs);
}
2)接下来对userRecHistory进行修改,修改完毕后需要再保存到redis中:
Builder recHistoryBuilder = UserRecHistoryPB.UserRecHistory.newBuilder(userRecHistory);
//修改
UserRecHistory build = recHistoryBuilder.build();
String KEY = MessageFormat.format(CacheConstants.CACHE_KEY_USER_HISTORY_PERF, deviceId);
int ttl = (int)(System.currentTimeMillis()/1000)+CacheConstants.CACHE_TIME_QUARTER;
couchbaseHistoryDao.set(KEY,
ttl,
build.toByteArray());
4、pb克隆:
pb的newBuilder就是一个深拷贝,类似于thrift的deepCopy();
Builder newBuilder = ApiLogPB.ApiLog.newBuilder();
newBuilder.setCost(10);
newBuilder.setChId("default");
newBuilder.setReqId("reqid");
newBuilder.setFNum(12);
newBuilder.setPuid("puid");
newBuilder.setUId("uid");
ApiLog apiLog = newBuilder.build();
//-----------
Builder newBuilder22 = apiLog.newBuilder();//深拷贝
类似于thtrift的:
InnerRequest pbdReq = innerRequest.deepCopy();