富客户端程序设计实例 - Action层 - Json 的序列化
Json 序列化是 RIA 应用程序特有的一步环节。Json是一种轻量级数据交换格式,他的出现替代了XMl文件作为平台无关的媒介。ExtJS作为视图层,需要与后台交换数据。交换的方式为Json串。这一部分是系统后台与前台的连接点。
查询记录
针对将查询结果集响应回视图所返回的Json串,是多条记录的集合。Json串示例样式:
{"results":13,"items":[{"id":"1","statu":1,"name":"1","pass":"9","age":9,"sex":"9","money":9,"email":"9","mobile":"9","managerId":9,"inTime":"9","outTime":"9"},……{}],"success":true}
这些内容会被ExtJS中的Model解析成一个个对象,然后显示在Ext.grid.Panel中显示对应的记录。
- /**
- * 将json数据写入此次响应流中
- * @param str json数据
- */
- private void jsonWriter(String str)
- {
- Writer writer = null;
- try
- {
- try
- {
- writer = ServletActionContext.getResponse().getWriter();
- writer.write(str);
- //ServletActionContext 在 package org.apache.struts2; 下。
- //getWriter() 在 package javax.servlet;下。
- }
- finally
- {
- writer.flush(); // 清除
- writer.close(); // 关闭
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- /**
- * 将查询结果集响应回视图
- * @param list 结果集
- * @param <T> 实体对象类型
- * @return json
- */
- protected <T> String ajaxJson(List<T> list)
- {
- String strs = "{\"results\":" + list.size() +
- ",\"items\":" + gson.toJson(list) + ",\"success\":true}";
- jsonWriter(strs);
- return strs;
- }
增加记录与修改记录
此时返回的是一条记录,对应的Json串如下
{"statu":"2","name":"2","pass":"2","age":2,"sex":"2","money":2,"email":"2","mobile":"2","managerId":2,"inTime":"2","outTime":"2"}
下一步需要将Json串转换成对象保存到List中,最后由DAO持久化到数据库里。getObjectFromJson返回的对象是:org.hongbo.Yangcl.entity.Employee@18e7a09。
- /**
- * 读取request中的json信息
- * @return jsonStr
- */
- protected String getJsonFromRequest()
- {
- String jsonStr = null;
- try
- {
- BufferedReader br = ServletActionContext.getRequest().getReader();
- jsonStr = br.readLine() ;
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return jsonStr;
- }
- /**
- * 将json解析成相应实体对象
- * @param json json数据
- * @param cla 实体类
- * @param <T> 实体对象类型
- * @return 实体对象
- */
- protected <T> T getObjectFromJson(String json, Class<T> cla)
- {
- if (StringUtils.isNotEmpty(json) && cla != null)
- {
- return gson.fromJson(json, cla);
- }
- return null;
- }
对应在EmployeeAction.java中
- public class EmployeeAction extends BaseAction
- {
- // 保存数据
- public void add()
- {
- String jsonStr = getJsonFromRequest();
- System.out.println("保存数据 Request" + jsonStr);
- List<Employee> empList = new ArrayList<Employee>();
- empList.add(getObjectFromJson(jsonStr, Employee.class));
- service.saveInfo(empList);
- }
- //更新数据
- public void update()
- {
- String jsonStr = getJsonFromRequest();
- System.out.println("更新数据 Request" + jsonStr);
- List<Employee> empList = new ArrayList<Employee>();
- empList.add(getObjectFromJson(jsonStr, Employee.class));
- service.updateInfo(empList);
- }
- }
删除记录
针对删除操作,substring(1,json.length()-1)去除字符串中的“【” 和 “】”。新字符串从原串的第二个字符开始,倒数第二个结束 。 在取得的字符串中的两条记录中,连接方式是这样的"outTime":"1"},{"id":"0001"( 两条记录间的连接方式: },{ )目的要将多条记录分割成数组,将 “,” 替换成 “$” 。故采用正则表达式转换连接方式为: }${ 。 \\ 是正则的特殊字符的表示。
局部测试代码
System.out.println(json.substring(1,json.length()-1).replaceAll(a,b )); //结果:"outTime":"1"}${"id":"4028800
- /**
- * 将json解析成相应实体对象集合 删除一条数据会用到
- * @param json json数据
- * @param cla 实体类
- * @param <T> 实体对象类型
- * @return 实体对象集合
- */
- protected <T> List<T> getListFromJson(String json, Class<T> cla)
- {
- if (StringUtils.isNotEmpty(json) && cla != null)
- {
- List<T> list = new ArrayList<T>();
- String[] strs = null;
- if(json.startsWith("[") && json.endsWith("]")) //删除多条记录会进入此分支
- {
- String a = "\\},\\{" ;
- String b = "\\}\\$\\{" ;
- strs = json.substring(1,json.length()-1).replaceAll(a,b ).split("\\$");
- }
- else if(json.startsWith("{") && json.endsWith("}")) //删除一条记录会进入此分支
- {
- strs = json.split("$"); //因为没有$这个字符,故字符串会被整体分割成一个数组
- }else
- {
- // TODO 异常信息处理
- }
- for(String str : strs)
- {
- list.add(gson.fromJson(str, cla));
- }
- return list;
- }
- return null;
- }