zoukankan      html  css  js  c++  java
  • 多层嵌套的json数据

    很多时候我们见到的json数据都是多层嵌套的,就像下面这般:

    {"name":"桔子桑",
      "sex":"",
      "age":18,
    "grade":{"gname":"三年八班",
             "gdesc":"初三年级八班"
             } 
     }

    要获得以上类型json数据,不外乎以下步骤:

    1.数据库查询

    sql:select s.name,s.sex,s.age,g.gname,g.gdesc

            from student s,grade g

            where s.gid = g.gid;        (你也可以选择用内连接的方法写)

    这样我们就查询到了想要的信息,很显然,查询结果是一个Object[]的集合。

    注意:由于大多数人都是对sql语句很熟悉,而对于hql语句不太熟悉,所以用hibernate框架查询的时候,

    有必要进行以下操作:

    String sql = "select s.sname,g.gname from student as s inner join grade as g on s.gid = g.gid WHERE s.sex = ? ";
    Query query = session.createSQLQuery(sql);
    query.setParameter(0, "男");
    List<Object[]> listDB = query.list();

    这样就显式地告诉hibernate执行sql查询,而不是hql查询,

    这两种查询还是有区别的,有时候sql语句放到hql查询里面执行是会出现错误的。

    2.新建javaBean

    其实开发工具会根据数据库多表之间的关系自动生成java实体类student,

    但是,大多时候是部分字段查询,如果将查询结果直接转给现有的javaBean,

    就会出现下面相同的情况,因为只查询了sname和gname字段,

    那么没查的字段在student实体类中则显示为空、0、[]

    [
    {"grade":{"gdesc":"","gid":0,"gname":"java","students":[]},
    "sex":"",
    "sid":0,"sname":"桔子桑"},
    {"grade":{"gdesc":"","gid":0,"gname":"java","students":[]},
    "sex":"",
    "sid":0,
    "sname":"eco"},
    {"grade":{"gdesc":"","gid":0,"gname":"java","students":[]},
    "sex":"",
    "sid":0,
    "sname":"官方"}
    ]

    所以我觉得有必要根据查询字段新建javaBean类,

    针对上面的查询,新建以下两个javaBean:

    //Ostudent类成员变量
    private String name;
    private String sex;
    private String age;
    private Ograde grade;
    
    //Ograde类成员变量
    private String gname;
    private String gdesc;

    3.查询结果的转化

    List<Object[]> listDB = query.list();
    List<Ostudent> listOut = new ArrayList();
    for (Object[] object : listDB) {
                String name = (String) object[0];
                String sex = (String) object[1];
                String age = (String) object[2];
                String gname = (String) object[3];
                String gdesc = (String) object[4];
                Ograde gra = new Ograde(gname,gdesc);
                Ostudent stu = new Ostudent(name,sex,age,gra);
                listOut.add(stu);
    }

    于是查询结果就转化成了n个Ostudent对象的集合。

    4.响应数据

    由于是Ostudent对象的集合,那么我们就可以用以下语句将其转为json字符串

    JSONArray array = JSONArray.fromObject(objOut);
    String jsonstr = array.toString();
    response.getWriter().print(jsonstr);

    这样就将查询结果以多层嵌套的json数据形式响应出去了。

    5.前端调用

    前端发起ajax请求成功之后,获得数据,我们在请求成功的回调函数里面可以这样写:

    var json = $.parseJSON( data );
    $.each(json, function (index, item) {   
            var name = json[index].name;   
            var age = json[index].age;
            var gname = json[index].grade.gname;     
    });

    是不是很简单?

    6.后台调用

    这里参考网上一个注释写得很全的,加以修改,然后记录下来

    public static String getjson(String path, String parameter, String method) {
            try {
                URL url = new URL(path);
                PrintWriter out = null;
                String line;
                StringBuilder sb = new StringBuilder();
                // 打开和url之间的连接
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                // 请求方式
                conn.setRequestMethod(method);
                // //设置通用的请求属性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent",
                        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                // 设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
                // 最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
                // post与get的 不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。
                conn.setDoOutput(true);
                conn.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                out = new PrintWriter(conn.getOutputStream());
                // 发送请求参数即数据
                out.print(parameter);
                // 缓冲数据
                out.flush();
                // 获取URLConnection对象对应的输入流
                InputStream is = conn.getInputStream();
                // 构造一个字符流缓存
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                // 关闭流
                is.close();
                // 断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
                // 固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。
                conn.disconnect();
                String str = sb.toString();
                return str;
            } catch (Exception e) {
                e.printStackTrace();
                return "出错喽";
            }
        }

    调用方法,获得json字符串,接下来就是将json字符串转化为java对象了

    String jsonstr = getjson(path, param, method);
            System.out.println(jsonstr);
            JSONArray jsonArray = JSONArray.fromObject(jsonstr); //json字符串转json数组
            Object[] arr = jsonArray.toArray();                  //json数组转普通Object数组
            for (Object o : arr) {                               //遍历这个Object数组
                JSONObject jsonObject = JSONObject.fromObject(o);//数组项(Object)转json对象
                Student stu = (Student) JSONObject
                        .toBean(jsonObject, Student.class);      //json对象转javaBean对象
                System.out.println(stu.getSname());              //访问javaBean对象的成员变量
            }

     注意:遍历的时候,这个o是不能直接强转Student对象的,虽然Myeclipse不会在你写代码的时候报错,

    但是,运行的时候,会对这种强转报以下错误:

    net.sf.json.JSONObject cannot be cast to eco.aaa.Student
  • 相关阅读:
    计算openlayers两点之间的距离
    node.js Tools for Visual Studio 介绍
    spring.net (3)依赖注入基础
    spring.net (2)环境搭建 对(1)例子的解释和扩充
    spring.net (1) 概念-控制反转(又名依赖注入)
    如何去定义一个jquery插件
    entityframework lamda 使用where时的注意事项
    k8s big-ip control 安装使用
    lb的keepalive问题
    firefox的fq设置图文教程- 【windows,mac通用】
  • 原文地址:https://www.cnblogs.com/eco-just/p/8503673.html
Copyright © 2011-2022 走看看