AJAX
JSON
概述:
• JSON(JavaScript Object Notation):JS 对象标记。
• 是一种轻量级的数据交换格式。
• 易于阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON语法(客户端)
JSON对象与JSON字符串
// JSON对象
var person = { name: "lz", age: 20, sex: "男" };
console.log(person.name);
console.log(person.age);
console.log(person.sex);
var arr = [1, 2, 3, 4];
// JSON字符串
var str = '{ "name": "lz", "age": 20, "sex": "男" }';
var str2 = "[1, 2, 3, 4]";
浏览器两者转换:
// 字符串->JSON对象
var p1 = JSON.parse(str);
alert(p1.name);
// JSON对象->字符串
var strjson = JSON.stringify(p1);
alert(strjson);
JSON 值:
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或false)
- 数组(在中括号中)
- 对象(在大括号中)
- null
JSON解析(服务端)
为什么需要解析?
- 浏览器和服务器之间交互采用JSON格式,但传输的是JSON字符串。
- 需要转成Java对象或JS对象,这种转换过程称为JSON解析。
[wppay]
服务器端采用
- FastJSON:阿里开发的专门用来处理JSON的工具包。
- Jackson:Jackson公司开发的一套处理JSON的API。(框架阶段使用)
测试类:
public class Book {
private String name;
private int price;
private Date date;
public Book(String name, int price, Date date) {
this.name = name;
this.price = price;
this.date = date;
}
//必须写
getter()\setter()
}
服务端JSON转为对象:
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=utf-8");
//对象必须要写getter与setter方法
Book book = new Book("图书", 20, new Date());
//1.把java对象转成Json字符串
String json = JSON.toJSONString(book);
response.getWriter().write(json);
}
- response.setContentType("text/html;charset=utf-8");
- response.setContentType("application/json;charset=utf-8");
我们这里使用了后者,明确的告诉浏览器我们传送的JSON字符串,而不是HTML。虽然也可以使用前者,在某些浏览器上没有问题,但是存在兼容性问题。
控制不序列化某些属性:
- @JSONField(serializable=false)
public class Book {
private String name;
//不序列化
@JSONField(serialize = false)
private int price;
private Date date;
......//接下类显示的都是去除价钱的
}
控制输出:
- SerializerFeature.PrettyFormat //美化输出
- SerializerFeature.WriteMapNullValue //输出null值
- SerializerFeature.WriteNullStringAsEmpty //将null转成“”
- SerializerFeature.DisableCircularReferenceDetect //禁用循环引用检测
String json = JSON.toJSONString(book, SerializerFeature.PrettyFormat);
说明:SerializerFeature.DisableCircularReferenceDetect //禁用循环引用检测
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=utf-8");
Book book = new Book("图书", 20, new Date());
Book book2 = new Book("图书", 20, new Date());
ArrayList<Object> list = new ArrayList<>();
list.add(book);
list.add(book2);
String json = JSON.toJSONString(list, SerializerFeature.PrettyFormat);
response.getWriter().write(json);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=utf-8");
Book book = new Book("图书", 20, new Date());
Book book2 = new Book("图书", 20, new Date());
ArrayList<Object> list = new ArrayList<>();
list.add(book);
list.add(book2);
list.add(book2);
String json = JSON.toJSONString(list, SerializerFeature.PrettyFormat);
response.getWriter().write(json);
}
处理:全部进行显示
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=utf-8");
Book book = new Book("图书", 20, new Date());
Book book2 = new Book("图书", 20, new Date());
ArrayList<Object> list = new ArrayList<>();
list.add(book);
list.add(book2);
list.add(book2);
String json = JSON.toJSONString(list, SerializerFeature.PrettyFormat,SerializerFeature.DisableCircularReferenceDetect);
response.getWriter().write(json);
}
将JSON字符串转为java对象
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=utf-8");
Book book = new Book("图书", 20, new Date());
Book book2 = new Book("图书", 20, new Date());
ArrayList<Object> list = new ArrayList<>();
list.add(book);
list.add(book2);
list.add(book2);
String json = JSON.toJSONString(list, SerializerFeature.PrettyFormat,SerializerFeature.DisableCircularReferenceDetect);
response.getWriter().write(json);
//2.把接收到的JSON字符串转换为java对象
List<Book> books = JSON.parseArray(json, Book.class);
for (Book book1 : books) {
System.out.println(book1.toString());
}
}
格式化日期
public class Book {
private String name;
//不序列化
@JSONField(serialize = false)
private int price;
@JSONField(format = "yyyy-MM-dd")
private Date date;
....
}
AJAX
概述:
- AJAX = Asynchronous JavaScript and XML。
- AJAX是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
AJAX使用步骤
1 创建XMLHttpRequest对象
- var xhr=new XMLHttpRequest();
2 设置回调函数
- xhr.onreadystatechange=function(){…}
3 打开连接
- xhr.open(method,url,async);
4 发送请求
- xhr.send(data);
GET请求
前端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax技术访问服务器</title>
</head>
<body>
<input type="button" value="发送get请求" onclick="click1()">
<script>
function click1() {
//1.创建XMLHttpRequest对象 (还有个兼容性写法PPT)
var xhr = new XMLHttpRequest();
//2.设置回调函数
//五种状态 一共执行四次
//0 初始状态,请求未建立连接
console.log(xhr.readyState);
//1 服务器连接已建立
//2 请求已经被接收
//3 请求处理中
//4 请求已经完成
xhr.onreadystatechange = function () {
console.log("---"+xhr.readyState)
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
//3.打开链接
// method:请求方式
// url:请求地址 url前写/还要加项目名
// async:true 异步
xhr.open("get", "LoginServlet?username=1&pwd=1", true);
//4.发送请求
xhr.send();
}
</script>
</body>
</html>
兼容各种浏览器写法:
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 浏览器
xhr = new XMLHttpRequest();
} else {
// IE6, IE5 浏览器执行代码
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
后端:
@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 pwd = request.getParameter("pwd");
if ("1".equals(username) && "1".equals(pwd)) {
response.getWriter().write("成功");
} else {
response.getWriter().write("失败");
}
}
status:
- 200:成功
- 404:资源未找到
- 500:服务器错误
POST请求
- 方式一:添加响应请求头,服务端不用修改
- 方式二:不添加,客户端发送JSON,服务端用流接
方式一:添加响应请求头,服务端不用修改
<input type="button" value="发送post请求" onclick="click2()">
<script>
function click2() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText)
}
}
xhr.open("post", "LoginServlet", true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.send("username=1&pwd=1");
}
</script>
方式二:不添加,客户端发送JSON,服务端用流接
若照着GET方式去写一个POST请求,如下:
function click2() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText)
}
}
xhr.open("post", "LoginServlet", true);
xhr.send("username=1&pwd=1");
}
点击按钮结果是失败。
先说下文件的表单类型,一共有三种:提交表单、文件表单、文本表单。
我们之前用Aajx进行请求相当于模拟了表单的请求,显然我们没有设置过表单类型。GET请求的参数是以URL参数的形式传递的,但POST的参数是用send()的方式发送的。默认表单类型是文本表单,前端发送的是文本表单,后端就要做出修改来接收文本表单的内容。如下
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
ServletInputStream is = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String data = br.readLine();
System.out.println(data);
//if ("1".equals(username) && "1".equals(pwd)) {
// response.getWriter().write("成功");
//} else {
// response.getWriter().write("失败");
//}
}
这里我们打印下数据格式为:username=1&pwd=1 普通的字符串。
我们可以自己处理这个字符串,但是太麻烦,不如客户端端直接传JSON字符串。
客户端:
function click2() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText)
}
}
xhr.open("post", "LoginServlet", true);
//JSON格式
xhr.send('{"username":"1","pwd":"1"}');
}
User类
public class User {
private String username;
private String pwd;
.......getter、setter
}
服务端:
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
ServletInputStream is = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String data = br.readLine();
System.out.println(data);
User user = JSON.parseObject(data, User.class);
if ("1".equals(user.getUsername()) && "1".equals(user.getPwd())) {
response.getWriter().write("成功");
} else {
response.getWriter().write("失败");
}
}
F12看一下请求的是什么表单:
浏览器的同源策略
同源策略:
- AJAX请求地址的协议、域名、端口号必须和页面所在的地址相同。
上图为正确,两个请求的协议、域名、端口号都相同。
什么时候会出现跨域问题?
例如:你当前程序8080端口请求了另一个程序8081端口的程序,这时就会出现跨域问题。这个问题是浏览器的问题,要求不能跨域访问。
解决跨域问题?
- JSONP(麻烦,不推荐)
- 在服务器添加("Access-Control-Allow-Origin", "*")响应头
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//添加解决跨域访问的响应头
response.setHeader("Access-Control-Allow-Origin", "*");
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
if("admin".equals(username)&&"888".equals(pwd)){
response.getWriter().write("登录成功");
}else{
response.getWriter().write("用户名或密码错误");
}
[/wppay]