Erlang 聊天室程序(三) 数据交换格式—json的decode

霸哥的blog中提到过Erlang服务器在通信中与客户端的数据交换方式:yufeng

为了简单起见这个聊天室程序采用json,要使用到rfc4627这个库

先定义一个Message类:

  1. public class Message {
  2.     String id;   //消息ID
  3.     String type; //消息类型
  4.     String from; //发送方
  5.     String to;   //接收方
  6.     String subject; //主题
  7.     String content; //内容
  8.     Date   creationDate; //时间
  9.     public Message(String type,String from,String to,String subject,String content){
  10.         this.id =MessageIdGenerator.nextId();
  11.         this.type=type;
  12.         this.from=from;
  13.         this.to=to;
  14.         this.subject=subject;
  15.         this.content=content;
  16.         this.creationDate=new Date();
  17.     }
  18.     public String getId() {
  19.         return id;
  20.     }
  21.     public void setId(String id) {
  22.         this.id = id;
  23.     }
  24.     public String getType() {
  25.         return type;
  26.     }
  27.     public void setType(String type) {
  28.         this.type = type;
  29.     }
  30.     public String getFrom() {
  31.         return from;
  32.     }
  33.     public void setFrom(String from) {
  34.         this.from = from;
  35.     }
  36.     public String getTo() {
  37.         return to;
  38.     }
  39.     public void setTo(String to) {
  40.         this.to = to;
  41.     }
  42.     public String getSubject() {
  43.         return subject;
  44.     }
  45.     public void setSubject(String subject) {
  46.         this.subject = subject;
  47.     }
  48.     public String getContent() {
  49.         return content;
  50.     }
  51.     public void setContent(String content) {
  52.         this.content = content;
  53.     }
  54.     public Date getCreationDate() {
  55.         return creationDate;
  56.     }
  57.     public void setCreationDate(Date creationDate) {
  58.         this.creationDate = creationDate;
  59.     }
  60. }

再定义一个JSON的工具类:

  1. public class JSONParaser {
  2.     public static JSONObject getJSON(Object content){
  3.         try{
  4.             JSONObject result = JSONObject.fromObject(content);
  5.             return result;
  6.         }
  7.         catch(Exception ex){
  8.             return null;
  9.         }
  10.     }
  11.     public static Object getString(String json){
  12.         try{
  13.             JSONObject jobj=JSONObject.fromObject(json);
  14.             return JSONObject.toBean(jobj);
  15.         }
  16.         catch(Exception ex){
  17.             return null;
  18.         }
  19.     }
  20. }

再修改SOCKET 发送部分代码:

  1. public void sendMsg(Message msg){
  2.     try {
  3.         String data=(JSONParaser.getJSON(msg)).toString();
  4.         oust.write(data.getBytes());
  5.         oust.flush();
  6.     } catch (IOException e) {
  7.         // TODO Auto-generated catch block
  8.         e.printStackTrace();
  9.     }
  10. }

测试下发送后服务器端接收到的数据:

  1. client_session dwmsg recived {message,undefined,msg,
  2.                                       [6],
  3.                                       undefined,undefined,
  4.                                       <<”{\”content\”:\”aaaaa\”,\”creationDate\”:{\”date\”:27,\”day\”:1,\”hours\”:13,\”minutes\”:10,\”month\”:1,\”seconds\”:26,\”time\”:1330319426281,\”timezoneOffset\”:-480,\”year\”:112},\”from\”:\”client1\”,\”id\”:\”x8yL-2\”,\”subject\”:\”chat\”,\”to\”:\”\”,\”type\”:\”msg\”}”>>,
  5.                                       undefined}
  6. client_session dwmsg sended

 

服务器端新建一个模块util_MessageParas,将收到的json数据转成内部可识的message:

  1. %% Author: Administrator
  2. %% Created: 2012-2-27
  3. %% Description: TODO: Add description to util_MessageParas
  4. -module(util_MessageParas).
  5. %%
  6. %% Include files
  7. %%
  8. %%-include(“json.hrl”).
  9. -include(“message.hrl”).
  10. %%
  11. %% Exported Functions
  12. %%<<”{\”content\”:\”aaa\”,\”creationDate\”:{\”date\”:27,\”day\”:1,\”hours\”:18,\”minutes\”:8,\”month\”:1,\”seconds\”:26,\”time\”:1330337306984,\”timezoneOffset\”:-480,\”year\”:112},\”from\”:\”client1\”,\”id\”:\”289n-2\”,\”subject\”:\”chat\”,\”to\”:\”\”,\”type\”:\”msg\”}”>>
  13. -export([paraseDecode/1]).
  14. %%
  15. %% API Functions
  16. %%
  17. %%
  18. %% Local Functions
  19. %%
  20. %paras json data to message
  21. paraseDecode(Bin)->
  22.     case rfc4627:decode(Bin) of
  23.         {ok,Obj,_Re}->
  24.             paraElements(Obj);
  25.         {error,Reason}->
  26.             {error,Reason}
  27.     end
  28. .
  29. %we get elements from decoded json,
  30. %it has to be 7 elements
  31. paraElements(Obj)->
  32.     {obj,List}=Obj,
  33.     Data =#message{},
  34.     %catch exception here
  35.     try paraEle(List,Data)
  36.     catch
  37.         {error,Reason,NewData}->
  38.             io:format(“Format”),
  39.             {error,Reason,NewData}
  40.     end
  41. .
  42. paraEle([Ele|Els],Data)->
  43.     NewData=para(Ele,Data),
  44.     paraEle(Els,NewData)
  45. ;
  46. paraEle([],Data)->
  47.     Data
  48. .
  49. %length of content should not more than 1000
  50. para({“content”,Val},Data) when is_binary(Val)->
  51.     io:format(“para content:~p~n”,[Data]),
  52.     Content=binary_to_list(Val),
  53.     if length(Content)<1000 ->
  54.                NewData=Data#message{content=Content},
  55.                io:format(“paraed content:~p~n”,[NewData]),
  56.                NewData;
  57.        true ->
  58.                throw({error,”illegal Content value”,Data})
  59.     end
  60. ;
  61. para({“to”,Val},Data) when is_binary(Val)->
  62.     io:format(“para to:~p~n”,[Data]),
  63.     To =binary_to_list(Val),
  64.     NewData=Data#message{to=To}
  65. ;
  66. para({“id”,Val},Data) when is_binary(Val)->
  67.     io:format(“para id:~p~n”,[Data]),
  68.     Id=binary_to_list(Val),
  69.     NewData=Data#message{id=Id}
  70. ;
  71. para({“subject”,Val},Data) when is_binary(Val)->
  72.     io:format(“para subject:~p~n”,[Data]),
  73.     Sub=binary_to_list(Val),
  74.     %we should validate subject here
  75.     if Sub=:=”chat” ->
  76.            NewData=Data#message{subject=Sub};
  77.        true ->
  78.          %throw exception
  79.          throw({error,”illegal subject value”,Data})
  80.     end
  81. ;
  82. para({“type”,Val},Data) when is_binary(Val)->
  83.     io:format(“para type:~p~n”,[Data]),
  84.     Type = binary_to_list(Val),
  85.     if Type=:=”msg”->
  86.            NewData=Data#message{type=Type};
  87.        true ->
  88.          %throw exception
  89.          throw({error,”illegal type value”,Data})
  90.     end
  91. ;
  92. para({“from”,Val},Data) when is_binary(Val)->
  93.     io:format(“para from:~p~n”,[Data]),
  94.     From=binary_to_list(Val),
  95.     NewData=Data#message{from=From}
  96. ;
  97. para({“creationDate”,Val},Data)->
  98.     Data
  99. ;
  100. para({Key,Val},Data)->
  101.     %no mache
  102.     %throw exception
  103.     throw({error,”unkown element”,Data})
  104. .
  105. paraseEncode()->
  106.     ok
  107. .

做下测试:

  1. util_MessageParas:paraseDecode(<<”{\”content\”:\”aaa\”,\”creationDate\”:{\”date\”:27,\”day\”:1,\”hours\”:18,\”minutes\”:8,\”month\”:1,\”seconds\”:26,\”time\”:1330337306984,\”timezoneOffset\”:-480,\”year\”:112},\”from\”:\”client1\”,\”id\”:\”289n-2\”,\”subject\”:\”chat\”,\”to\”:\”\”,\”type\”:\”msg\”}”>>).
  2. para content:{message,undefined,undefined,undefined,undefined,undefined,
  3.                       undefined,undefined}
  4. paraed content:{message,undefined,undefined,undefined,undefined,undefined,
  5.                         ”aaa”,undefined}
  6. para from:{message,undefined,undefined,undefined,undefined,undefined,”aaa”,
  7.                    undefined}
  8. para id:{message,undefined,undefined,”client1″,undefined,undefined,”aaa”,
  9.                  undefined}
  10. para subject:{message,”289n-2″,undefined,”client1″,undefined,undefined,”aaa”,
  11.                       undefined}
  12. para to:{message,”289n-2″,undefined,”client1″,undefined,”chat”,”aaa”,
  13.                  undefined}
  14. para type:{message,”289n-2″,undefined,”client1″,[],”chat”,”aaa”,undefined}
  15. {message,”289n-2″,”msg”,”client1″,[],”chat”,”aaa”,undefined}

OK,收到的数据可以正常地解析为message了。

注:

在此处只需要将json数据的外层转换为message消息。message消息针对不同的类型和作用会有不同的json内容,所以内层数据应该在具体的消息处理部分再调用相应的paras处理。



发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(Spamcheck Enabled)