【第49天】JSON的创建(封装)方法、传输格式以及应用

版权声明:©2018 本文為博主來秋原創,轉載請註明出處,博主保留追責權利。 https://blog.csdn.net/qq_30257081/article/details/86483801

1 JSON

       JSON(JavaScript Object Notation,JS对象表示法),一种轻量级的数据交换格式。2004年诞生,2006年加入的ajax技术体系,用来取代xml封装批量的数据,本质上就是一个特殊格式的字符串,可以直接打印。被称之为Java的第十种数据类型。

1.1 两种传输格式

  • {key1:value1,key2:value2,keyN:valueN},其中,key和value分别可以的取值是:
    key: 只能是字符串
    value: 八种基本数据类型、String、null、自定义数据类型、数组、JSON
  • [value1,value2,value3,valueN],其中,key和value分别可以的取值是:
    value: 八种基本数据类型、String、null、自定义数据类型、数组、JSON

1.2 三种创建(封装)方法

       JSON存在三种封装方式,可以封装成以上两种格式的JSON数据。

package com.test.test;

import com.test.po.Student;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import java.util.*;

public class Test {
    public static void main(String[] args) {
        //1)可以封装任意格式的数据,封装之后呈现格式1的JSON
        //但这样的格式在存入JSON时存放了一些key值,这些值很多情况下都是垃圾数据
        int i = 3;
        String str = "测试JSON方法1";
        boolean flag = true;
        String[] strArray = {"Java", "C++", "Python"};

        JSONObject jo = new JSONObject();
        jo.put("key1", i);
        jo.put("key2", str);
        jo.put("key3", flag);
        jo.put("key4", strArray);
        jo.put("key5", new Student(1, "张三", "[email protected]", "111222"));
        System.out.println(jo);
        //输出{"key1":3,"key2":"测试JSON方法1","key5":{"phone":"111222","name":"张三","id":1,"isdeleted":0,"email":"[email protected]"},
        //"key3":true,"key4":["Java","C++","Python"]}


        //2)可以封装自定义数据类型和Map,封装之后呈现格式1的JSON
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "VUE");
        map.put(2, "React");
        map.put(3, "Angular");
        map.put(4, "jQuery");

        //存Map
        JSONObject js1 = JSONObject.fromObject(map);
        System.out.println(js1);
        //输出{"1":"VUE","2":"React","3":"Angular","4":"jQuery"}

        //存自定义数据类型
        JSONObject js2 = JSONObject.fromObject(
                new Student(2, "李四", "[email protected]", "111223"));
        System.out.println(js2);
        //输出{"phone":"111223","name":"李四","id":2,"isdeleted":0,"email":"[email protected]"}

        //有选择地对自定义数据类型中的属性封装
        JsonConfig jc = new JsonConfig();
        //将不需要封装的属性列出
        jc.setExcludes(new String[]{"id", "name", "phone"});
        JSONObject js3 = JSONObject.fromObject(
                new Student(3, "王五", "[email protected]", "111224"), jc);
        System.out.println(js3);
        //输出{"isdeleted":0,"email":"[email protected]"}


        //3)专门用来封装List、数组和Set,封装之后呈现格式2的JSON
        //String[] strArray = {"Java", "C++", "Python"};
        JSONArray ja1 = JSONArray.fromObject(strArray);
        System.out.println(ja1);
        //输出["Java","C++","Python"]

        List<String> list = new ArrayList<>();
        list.add("HTML5");
        list.add("CSS3");
        list.add("JS6");
        JSONArray ja2 = JSONArray.fromObject(list);
        System.out.println(ja2);
        //输出["HTML5","CSS3","JS6"]

        Set<String> set = new HashSet<>();
        set.add("山东鲁能");
        set.add("广州恒大");
        set.add("上海申花");
        set.add("大连一方");
        JSONArray ja3 = JSONArray.fromObject(set);
        System.out.println(ja3);
        //输出["广州恒大","上海申花","山东鲁能","大连一方"]
    }
}

2 AJAX和原生JS通过JSON传输实现级联两个组件

      使用AJAX和原生的JS实现下拉列表选中省份(直辖市)时,市(区)自动出现在右边的下拉列表中。

  • 编写dao层实现类
package com.test.dao;

import com.test.factory.Factory;
import com.test.po.City;
import com.test.po.Province;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.Connection;
import java.util.List;

public class ProvinceCityDaoImpl implements ProvinceCityDaoIf{

    Connection conn;
    QueryRunner qr = new QueryRunner();

    /**
     * 拿取全部省份 省份字段:id name
     */
    @Override
    public List<Province> queryProvince() {
        try {
            String sql = "select * from province";
            conn = Factory.getCon();
            return qr.query(conn, sql, new BeanListHandler<Province>(Province.class));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据pid拿取城市 城市字段:id name pid(省份表的id)
     *
     * @param pid
     */
    @Override
    public List<City> queryCityByPid(Integer pid) {
        try {
            String sql = "select * from city where pid = ?";
            conn = Factory.getCon();
            return qr.query(conn, sql, new BeanListHandler<City>(City.class), pid);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
  • 先将省份在下拉列表中显示

cascade.html

<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>级联</title>
    </head>
    <body onload="showProvince()">
        <label for="province">请选择省份:</label>
        <select name="province" id="province">
            <option value="0">===选择省份===</option>
        </select>

        <label for="city">请选择城市:</label>
        <select name="city" id="city">
            <option value="0">===选择城市===</option>
        </select>
        <script>
            let request;

            function create(){
                request = new XMLHttpRequest();
            }

            function showProvince(){
                create();
                request.open("post", "showProvince", true);
                request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                request.onreadystatechange = function(){
                    if(request.readyState == 4){
                        if(request.status == 200){
                            let text = request.responseText;
                            //{"province":[{"name":"山东","id":1},
                            //{"name":"上海","id":2},
                            //{"name":"广东","id":3},
                            //{"name":"台湾","id":4}]}
                            
                            /*
                            * 从服务器返回的数据是一个普通的字符串
                            * 我们无法方便地拿取内部封装的数据,
                            * 通过JS内置的转换器可以将一个标准的
                            * JSON字符串转换成JS对象
                            *
                            * 转换规则如下:
                            *   1)JSON的key值全部转换为JS对象的属性名
                            *   2)JSON的value值全部转换为JS对象的属性值
                            *
                            *   JSON ---> Object
                            *   若使用第三种封装方式,可以直接parse为数组
                            * */
                            let obj = JSON.parse(text);
                            //Object
                            // province: Array(4)
                            // 0: {name: "山东", id: 1}
                            // 1: {name: "上海", id: 2}
                            // 2: {name: "广东", id: 3}
                            // 3: {name: "台湾", id: 4}

                            let array = obj.province;
                            //Array(4)
                            // 0: {name: "山东", id: 1}
                            // 1: {name: "上海", id: 2}
                            // 2: {name: "广东", id: 3}
                            // 3: {name: "台湾", id: 4}

                            //拿取省份下拉列表框
                            let dom_select = document.getElementById("province");

                            //将数据填入下拉列表中
                            for(let i = 0; i < array.length; i++){
                                let province = array[i];
                                let id = province.id;
                                let name = province.name;
                                /*
                                *   向下拉列表框中动态添加option下拉项
                                *   等号左边:options 中括号内为[index]
                                *   等号右边:Option 小括号内(页面显示的值,value值);
                                *
                                * */
                                dom_select.options[i + 1] = new Option(name, id);
                            }

                        }
                    }
                };
                request.send(null);
            }
        </script>
    </body>
</html>

编写Servlet类,接收请求并返回省份的数据

package com.test.servlet;

import com.test.dao.ProvinceCityDaoIf;
import com.test.dao.ProvinceCityDaoImpl;
import com.test.po.Province;
import net.sf.json.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

public class ShowProvince extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/plain;charset=utf-8");

        PrintWriter out = response.getWriter();
        ProvinceCityDaoIf dao = new ProvinceCityDaoImpl();

        //拿取全部省份
        List<Province> list = dao.queryProvince();
        //第一种封装方法
        JSONObject jo = new JSONObject();
        jo.put("province", list);
        System.out.println(jo);
        out.print(jo);
        out.close();
    }
}

效果图:
在这里插入图片描述

  • 再实现城市的级联显示
    在select标签中添加onchange=“showCity(this.value)”,this.value指的是当前选择的option标签对应的value。

向cascade.html中追加

 function showCity(pid){
     create();
     //这里选用一次GET请求方式
     //使用get时需要后面new一个Date(),
     //因为是明文传输,浏览器的地址栏可能会有缓存之前的数据,
     //所以要加一个每次都不一样的时间,即new Date(),防止浏览器使用之前的缓存发送请求
     //另外,get默认是字符流,不需要定义字符集Content-Type
     request.open("get", "showCity?pid=" + pid + "&time=" + new Date(), true);
     request.onreadystatechange = function(){
         if(request.readyState==4){
             if(request.status == 200){
                 //当选中的为山东省
                 let text = request.responseText;
                 //[{"name":"济南","pid":1,"id":1},
                 // {"name":"青岛","pid":1,"id":2},
                 // {"name":"淄博","pid":1,"id":3},
                 // {"name":"枣庄","pid":1,"id":4},
                 // {"name":"烟台","pid":1,"id":5},
                 // {"name":"潍坊","pid":1,"id":6},
                 // {"name":"济宁","pid":1,"id":7},
                 // {"name":"泰安","pid":1,"id":8}]

                 //使用第三种封装方式,可以省一步,数组不需要再转类型
                 let array = JSON.parse(text);
                 //(8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
                 //0: {name: "济南", pid: 1, id: 1}
                 //1: {name: "青岛", pid: 1, id: 2}
                 //2: {name: "淄博", pid: 1, id: 3}
                 //3: {name: "枣庄", pid: 1, id: 4}
                 //4: {name: "烟台", pid: 1, id: 5}
                 //5: {name: "潍坊", pid: 1, id: 6}
                 //6: {name: "济宁", pid: 1, id: 7}
                 //7: {name: "泰安", pid: 1, id: 8}
                 
                 //拿取城市下拉列表框
                 let dom_select = document.getElementById("city");

                 //以防城市的列表框切换后还留存上一次的数据,
                 //向其中加入数据,若原来的省份对应的城市数量多于这次的数量,
                 //会出现两个省份的城市混排的现象
                 while(dom_select.length > 1){
                     dom_select.removeChild(dom_select.item(1));
                 }

                 for(let i = 0; i < array.length; i++){
                     let city = array[i];
                     let id = city.id;
                     let name = city.name;
                     dom_select.options[i + 1] = new Option(name, id);
                 }
             }
         }
     };
     request.send(null);
 }

编写Servlet类,按接收GET请求的参数返回城市的数据

package com.test.servlet;

import com.test.dao.ProvinceCityDaoIf;
import com.test.dao.ProvinceCityDaoImpl;
import net.sf.json.JSONArray;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ShowCity extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/plain;charset=utf-8");

        ProvinceCityDaoIf dao = new ProvinceCityDaoImpl();
        //使用第三种封装方式
        JSONArray ja = JSONArray.fromObject(
                dao.queryCityByPid(
                        Integer.parseInt(
                                request.getParameter("pid"))));

        PrintWriter out = response.getWriter();
        out.print(ja);
        System.out.println(ja);
        out.close();
    }
}

效果图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_30257081/article/details/86483801
今日推荐