Day43
JSON
简介:
JSON:JavaScript Object Notation是一种表示对象的方式
基于JavaScript语言的轻量级的数据交换格式;(即:用来传输数据的一种格式)
现在传输数据都是用的JSON格式,渐渐替代了xml格式。xml格式和JSON格式的优缺点:
同样的数据量,JSON格式占用空间更少,但是JSON可读性较差。
XML可读性高,一般用作配置文件,但是同样的数据量,XML格式占用空间更多。
注意:客户端和服务端交互,传输的XML格式或者JSON格式都是字符串!
掌握的技能就是在客户端和服务端生成和解析JSON格式的字符串。
客户端中处理JSON
解析JSON -> JS对象
<body> <script type="text/javascript"> //var jsonStr = '{"name":"张三","age":18}'; //var jsObj = JSON.parse(jsonStr); //console.log(jsObj.name); //console.log(jsObj.age); var jsonStr = '{"name":"张三","age":18}'; var jsObj = eval("("+jsonStr+")"); console.log(jsObj.name); console.log(jsObj.age); </script> </body>
注:必须单引号包裹双引号,key必须使用双引号包裹。建议:使用eval():将字符串认为是JS代码去执行,但由于JSON是以“{}”的方式开始以及结束的,会被当做代码块,所以要加上小括号让它去理解并解析。
解析JSON格式的字符串 ->JS数组
<body> <script type="text/javascript"> var jsonStrs = "[{'name':'张三','age':18},{'name':'李四','age':24}]"; var jsArr = eval(jsonStrs); for (var i=0;i<jsArr.length;i++) { console.log(jsArr[i].name); console.log(jsArr[i].age); } </script> </body>
注:因为数组外面是中括号,所以eval方法里不用再加小括号。
JS对象 -> 解析成JSON格式的字符串
<body> <script type="text/javascript"> function Student(name,age){ this.name = name; this.age = age; } var stuObj1 = new Student("张三",18); var jsonStr = JSON.stringify(stuObj1); console.log(jsonStr); </script> </body>
注:JSON.stringify(obj)方法。
JS数组 -> 解析成JSON格式的字符串
<body> <script type="text/javascript"> function Student(name,age){ this.name = name; this.age = age; } var stuObj1 = new Student("张三",18); var stuObj2 = new Student("李四",19); var stus = [stuObj1,stuObj2]; var jsonStr = JSON.stringify(stus); console.log(jsonStr); </script> </body>
服务端(Java)中处理JSON
如果使用逻辑或Java原生解析类去解析JSON是非常麻烦的,项目中大多数会使用FastJSON和Jackson来操作JSON
FastJSON
特点:
名声大(阿里制作),速度快,功能强大,零依赖。
创建resources包,设为资源,放入fastjson的jar包,导包。
场景:
Author:
package com.qf; public class Author { private String name; private String info; public Author() { } public Author(String name, String info) { this.name = name; this.info = info; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } @Override public String toString() { return "Author{" + "name='" + name + '\'' + ", info='" + info + '\'' + '}'; } }
Book:
package com.qf; public class Book { private String name; private double price; private Author author; public Book() { } public Book(String name, double price, Author author) { this.name = name; this.price = price; this.author = author; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Author getAuthor() { return author; } public void setAuthor(Author author) { this.author = author; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", price=" + price + ", author=" + author + '}'; } }
JSON字符串转Java对象
public static void main(String[] args) { String jsonStr = "{name:'Java从入门到精通',price:100,author:{name:'张三',info:'从业Java20年'}}"; Book book = JSON.parseObject(jsonStr, Book.class); System.out.println(book); }
JSON字符串转Java数组
public static void main(String[] args) { String jsonStr = "[{name:'Java从入门到精通',price:100,author:{name:'张三',info:'从业Java20年'}},{name:'Sql从删库到跑路',price:999,author:{name:'李四',info:'精通数据库的安装和卸载'}}]"; //将JSON格式的字符串转换为JSONArray对象 JSONArray jsonArray = JSONArray.parseArray(jsonStr); //创建Java数组 Book[] books = new Book[jsonArray.size()]; //遍历jsonArray,将里面的元素(JSONObject)取出并转换为Java对象 for (int i = 0; i < jsonArray.size(); i++) { Book book = jsonArray.getObject(i, Book.class); books[i] = book; } for (Book book : books) { System.out.println(book); } }
JSON字符串转Java的List集合
public class Test03 { public static void main(String[] args) { String jsonStr = "[{name:'Java从入门到精通',price:100,author:{name:'张三',info:'从业Java20年'}},{name:'Sql从删库到跑路',price:999,author:{name:'李四',info:'精通数据库的安装和卸载'}}]"; //将JSON格式的字符串转换为集合对象 List<Book> books = JSONArray.parseArray(jsonStr, Book.class); for (Book book : books) { System.out.println(book); } } }
经验:不转为数组,转为集合,更简便。
JSON字符串转Java的Map集合
public static void main(String[] args) { String jsonStr = "{'001':{name:'Java从入门到精通',price:100,author:{name:'张三',info:'从业Java20年'}},'002':{name:'Sql从删库到跑路',price:999,author:{name:'李四',info:'精通数据库的安装和卸载'}}}"; HashMap<String, Book> bookMap = new HashMap<>(); //将JSON格式的字符串转换为Map集合对象 Map<String, JSONObject> map = (Map<String, JSONObject>) JSON.parse(jsonStr); Set<Map.Entry<String, JSONObject>> entries = map.entrySet(); for (Map.Entry<String, JSONObject> entry : entries) { String key = entry.getKey(); JSONObject value = entry.getValue(); //将JSONObject对象转换为Book对象 Book book = JSONObject.toJavaObject(value, Book.class); bookMap.put(key,book); } Set<Map.Entry<String, Book>> bookEntries = bookMap.entrySet(); for (Map.Entry<String, Book> bookEntry : bookEntries) { System.out.println(bookEntry.getKey()+"--"+bookEntry.getValue()); } }
Java对象转JSON格式字符串
public static void main(String[] args) { Author author = new Author("张三", "精通Java的安装与下载"); Book book = new Book("Java从入门到精通", 999, author); //Java对象 转 JSON字符串 String jsonStr0 = JSON.toJSONString(book); System.out.println(jsonStr0); }
添加过滤器:
public static void main(String[] args) { Author author = new Author("张三", "精通Java的安装与下载"); Book book = new Book("Java从入门到精通", 999, author); //Java对象 转 JSON字符串 // String jsonStr0 = JSON.toJSONString(book); // System.out.println(jsonStr0); String jsonStr = JSON.toJSONString(book, new PropertyFilter() { @Override public boolean apply(Object o, String s, Object o1) { if (o instanceof Author && s.equals("name")) { return false; } return true; } }); System.out.println(jsonStr); }
Java数组转JSON格式字符串
public static void main(String[] args) { Author author1 = new Author("张三", "精通Java的安装与下载"); Book book1 = new Book("Java从入门到精通", 999, author1); Author author2 = new Author("李四", "精通MySql的安装与下载"); Book book2 = new Book("MySql从删库到跑路", 999, author2); Book[] books = new Book[]{book1,book2}; String jsonString = JSON.toJSONString(books); System.out.println(jsonString); }
Java的List集合转JSON格式字符串
public static void main(String[] args) { Author author1 = new Author("张三", "精通Java的安装与下载"); Book book1 = new Book("Java从入门到精通", 999, author1); Author author2 = new Author("李四", "精通MySql的安装与下载"); Book book2 = new Book("MySql从删库到跑路", 999, author2); List<Book> books = Arrays.asList(book1,book2); String jsonString = JSON.toJSONString(books); System.out.println(jsonString); }
Java的Map集合转JSON格式字符串
public static void main(String[] args) { Author author1 = new Author("张三", "精通Java的安装与下载"); Book book1 = new Book("Java从入门到精通", 999, author1); Author author2 = new Author("李四", "精通MySql的安装与下载"); Book book2 = new Book("MySql从删库到跑路", 999, author2); Map<String,Book> map = new HashMap<>(); map.put("001",book1); map.put("002",book2); String jsonString = JSON.toJSONString(map); System.out.println(jsonString); }
Ajax
简介:Ajax:(Asynchronous JavaScript And XML)指异步 JavaScript 及 XML
他不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript、XML、HTML、CSS新用法
Ajax指的是刷新局部页面的技术。
XMLHttpRequest对象
该对象用于在前台与服务器交换数据。即对网页进行局部更新,除了IE5和IE6使用ActiveXObject外所有现代浏览器均支持XMLHttpRequest对象。
//获取XMLHttpRequest对象 function getXMLHttpRequest() { var xmlHttp; if (window.XMLHttpRequest) {// 新浏览器 xmlHttp = new XMLHttpRequest(); }else if (window. ActiveXObject) {// IE6及以下浏览器 xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP"); } return xmlHttp; }
与服务器交换数据-open/send
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <button οnclick="fun01()">向Servlet01发送请求</button> <button οnclick="fun02()">向Servlet02发送请求</button> </body> <script type="text/javascript"> function fun01(){ var xmlHttp = getXMLHttpRequest(); //给xmlHttp对象绑定onreadystatechange事件 xmlHttp.onreadystatechange = function (){ if(xmlHttp.readyState == 4){//响应已就绪 if(xmlHttp.status == 200){//判断响应状态码 var text = xmlHttp.responseText; alert(text); } } } xmlHttp.open("GET","Servlet01?username=zs&password=123123&name=张三",true); xmlHttp.send(); } function fun02(){ var xmlHttp = getXMLHttpRequest(); xmlHttp.onreadystatechange = function (){ if(xmlHttp.readyState == 4){ if(xmlHttp.status == 200){ var text = xmlHttp.responseText; alert(text); } } } xmlHttp.open("POST","Servlet02",true); //post需要设置请求头 xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); xmlHttp.send("username=wyz&password=123456&name=吴彦祖"); } function getXMLHttpRequest(){ var xmlHttp; if(window.XMLHttpRequest){ xmlHttp = new XMLHttpRequest(); }else if(window.ActiveXObject){ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlHttp; } </script> </html>
Servlet01:
package com.qf.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PipedWriter; import java.io.PrintWriter; @WebServlet("/Servlet01") public class Servlet01 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); String name = request.getParameter("name"); System.out.println(username+"--"+password+"--"+name); PrintWriter pw = response.getWriter(); pw.write("呵呵呵"); } }
Servlet02:
package com.qf.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/Servlet02") public class Servlet02 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); String name = request.getParameter("name"); System.out.println(username+"--"+password+"--"+name); PrintWriter pw = response.getWriter(); pw.write("呵呵呵"); } }
注:onreadystatechange事件:
函数 描述 onreadystatechange 每当 readyState 属性改变时,就会调用该函数。
属性 描述 readyState 存有 XMLHttpRequest 的状态。
从 0 到 4 发生变化:
0 - 请求未初始化服务器
1 - 连接已建立
2 - 请求已接收
3 - 请求处理中
4 - 请求已完成,且响应已就绪status 存有响应的状态。
200 - OK
404 - 未找到页面
案例1:注册账号提示
注册页面,账号显示能不能用
StudentController:
public void isRegister(HttpServletRequest request,HttpServletResponse response) throws IOException { String username = request.getParameter("username"); boolean isRegister = studentService.isRegister(username); if(isRegister){ response.getWriter().write("1"); }else { response.getWriter().write("-1"); } }
register.jsp:
var bool = false; document.getElementById("registerForm").onsubmit = function (){ return bool;//只有账号可以注册时才允许提交 }; var span = document.getElementsByTagName("span")[0]; var username = document.getElementById("username"); username.onblur = function (){ var xmlHttp = getXMLHttpRequest(); //给xmlHttp对象绑定onreadystatechange事件 xmlHttp.onreadystatechange = function (){ if (xmlHttp.readyState == 4){//响应已就绪 if(xmlHttp.status == 200){//判断响应状态码 var text = xmlHttp.responseText;//获取响应数据 if (text == "1"){ span.innerText = "恭喜,账号可以注册"; span.style.color = "green"; bool = true; }else if (text == "-1"){ span.innerText = "抱歉,该账号已被注册"; span.style.color = "red"; bool = false; } } } } xmlHttp.open("GET","Student?action=isRegister&username="+username.value,true); xmlHttp.send(); } function getXMLHttpRequest(){ var xmlHttp; if(window.XMLHttpRequest){ xmlHttp = new XMLHttpRequest(); }else if(window.ActiveXObject){ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlHttp; }
案例2:二级联动
思路:Mapper层:用户拿到所有的省份以及通过parent_code拿到省份对应的城市数据。
Service层:把所有的省份数据和相应的城市数据用JSON.toJSONString()方法转换成json格式的字符串,返回字符串。
controller层:把拿到的json字符串用response.getWriter().write()方法(字符流中的打印流)返回到页面中。
jsp页面:通过Ajax获得数据,并在select中创建option,设置其value和innerText。
register.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial, sans-serif; background: #f0f0f0; } </style> </head> <body> <form id="registerForm" action="Student?action=register" method="post" enctype="multipart/form-data"> ${msg} <h2>欢迎来到注册页面</h2> <br/> 账号:<input type="text" name="username" id="username"/><span></span><br/> 密码:<input type="password" name="password" /><br /> 姓名:<input type="text" name="name" /><br /> 年龄:<input type="text" name="age" /><br /> 性别: <input type="radio" name="sex" value="man" checked="checked"/>男 <input type="radio" name="sex" value="woman"/>女 <br /> 爱好: <input type="checkbox" name="hobbies" value="football" />足球 <input type="checkbox" name="hobbies" value="basketball" />篮球 <input type="checkbox" name="hobbies" value="shop" />购物 <br /> 籍贯: <select id="province" name="province"> <option value="null">---请选择---</option> </select>省 <select id="city" name="city"> <option value="null">---请选择---</option> </select>市 <br/> <input type="file" name="photo"/><br/> <input type="submit" value="注册" /> <button type="button" οnclick="fun01()">返回</button> </form> <script type="text/javascript"> function fun01(){ window.location = "welcome.html"; } var province = document.getElementById("province"); function showProvince() { var xmlHttp = getXMLHttpRequest(); xmlHttp.onreadystatechange= function (){ if(xmlHttp.readyState==4){ if(xmlHttp.status==200){ var text = xmlHttp.responseText; var pros = eval(text); for (let i = 0; i < pros.length; i++) { var option = document.createElement("option"); option.value = pros[i].code; option.innerText = pros[i].name; province.appendChild(option); } } } }; xmlHttp.open("GET","User?action=getProvinces",true); xmlHttp.send(); } showProvince(); var city = document.getElementById("city"); province.onchange = function (){ var parentCode = this.value; var xmlHttp = getXMLHttpRequest(); xmlHttp.onreadystatechange = function (){ if(xmlHttp.readyState==4){ if(xmlHttp.status==200){ city.length=0; var text = xmlHttp.responseText; var cities = eval(text); console.log(cities); for (let i = 0; i < cities.length; i++) { var option = document.createElement("option"); option.value =cities[i].code; option.innerText =cities[i].name; city.appendChild(option); } } } }; xmlHttp.open("GET","User?action=getCities&parentCode="+parentCode,true); xmlHttp.send(); }; var bool = false; document.getElementById("registerForm").onsubmit = function (){ return bool;//只有账号可以注册时才允许提交 }; var span = document.getElementsByTagName("span")[0]; var username = document.getElementById("username"); username.onblur = function (){ var xmlHttp = getXMLHttpRequest(); //给xmlHttp对象绑定onreadystatechange事件 xmlHttp.onreadystatechange = function (){ if (xmlHttp.readyState == 4){//响应已就绪 if(xmlHttp.status == 200){//判断响应状态码 var text = xmlHttp.responseText;//获取响应数据 if (text == "1"){ span.innerText = "恭喜,账号可以注册"; span.style.color = "green"; bool = true; }else if (text == "-1"){ span.innerText = "抱歉,该账号已被注册"; span.style.color = "red"; bool = false; } } } }; xmlHttp.open("GET","Student?action=isRegister&username="+username.value,true); xmlHttp.send(); }; function getXMLHttpRequest(){ var xmlHttp; if(window.XMLHttpRequest){ xmlHttp = new XMLHttpRequest(); }else if(window.ActiveXObject){ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlHttp; } </script> </body> </html>