目录
一.JSON 简介
1.介绍
2.为什么要使用 JSON
二.JSON 格式的特征
1.JSON 的语法规则
2. JOSN 的 6 种数据类型
三.Jackson
1.Jackson 的使用
2.Jackson 简介
3.在响应中通过 JSON 格式传递数据
四.通过 JSON 格式在响应中传递单个对象
五.通过 JSON 格式在响应中传递多个对象
?六.在 JSON 中通过 Map 传递数据
七.在请求中通过 JSON 格式传递数据
?八.Jackson 的常用注解
1.@JsonProperty
2.@JsonIgnore
3.@JsonFormat
九.Jackson 工具类的使用
一.JSON 简介
1.介绍
JSON(JavaScript Object Notation)
是一种基于字符串的轻量级的数据交换格式。易于人阅
读和编写,同时也易于机器解析和生成。
JSON
是
JavaScript
数据类型的子集。
2.为什么要使用 JSON
在
JSON
未出现之前在
Ajax
中对于数据传递方式,会使用
XML
作为主要数据格式来传输数据。直到
JSON
出现后逐渐放弃使用
XML
作为数据传输格式。
JSON
比
XML 更小、更快,更易解析。
二.JSON 格式的特征
1.JSON 的语法规则
JSON
是按照特定的语法规则所生成的字符串结构。
- 大括号表示 JSON 的字符串对象。{ }
- 属性和值用冒号分割。{"属性":"value"}
- 属性和属性之间用逗号分割。{"属性":"value","属性":"value",...}
- 中括号表示数组。[{"属性":"value"...},{"属性":"value"...}]
JSON 字符串对象:
{"userid":1,"username":"admin","sex":"male"}
数组:
[{"userid":1,"username":"admin"},{"userid":2,"username":"oldlu"}]?
2. JOSN 的 6 种数据类型
- string:字符串,必须要用双引号引起来。
- number:数值,与 JavaScript 的 number 一致,
- object:JavaScript 的对象形式,{ key:value }表示方式,可嵌套。
- array:数组,JavaScript 的 Array 表示方式[ value ],可嵌套。
- true/false:布尔类型,JavaScript 的 boolean 类型。
- null:空值,JavaScript 的 null。
三.Jackson
1.Jackson 的使用
在
JDK
中并没有内置操作
JSON
格式数据的
API
,因此使用处理
JSON
格式的数据需要借
助第三方类库。
几个常用的
JSON
解析类库:
Gson:
谷歌开发的
JSON
库,功能十分全面。
FastJson:
阿里巴巴开发的
JSON
库,性能十分优秀。
Jackson:
社区十分活跃且更新速度很快。被称为“最好的
Json
解析器”
2.Jackson 简介
Jackson
是一种解析
JSON
格式数据的
API
,也是最流行,速度最快的
JSON API
。在
SpringMVC
中默认使用
Jackson API
处理
JSON
格式的数据。
Jackson
下载地址:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
上面三个都要下载,以第一个为例,输入网址,红框处选择版本
然后点击View All
下载相应jar包:
3.在响应中通过 JSON 格式传递数据
在响应中使用 Jackson 处理 JSON 格式数据的步骤:
- 添加 jackson-annotations.jar、jackson-core.jar、jackson-databind.jar
- 通过 jackson API 将 Java 对象转换 JSON 格式
- 修改响应头,响应类型为 application/json
- 将结果基于字符输出流推回客户端浏览器
- 在页面的中通过 JavaScript 的 JSON.parse()函数将 JSON 格式的数据转换为 JavaScript对象
四.通过 JSON 格式在响应中传递单个对象
需求:
定义一个
Users
类,包含
userid
、
username
属性。
实例化一个
Users
对象,通过
JSON
格式将
Users
对象响应到客户端浏览器。
将
Users
对象中的数据插入到页面中。
还是上篇文章中导入servlet-api.jar的操作,导入jackson的三个jar包
然后再像下图一样,右键ajaxTest,点击 Put into Output Root,然后点击Apply,再点OK
项目结构:
Users.java:
右键--》Generate--》Getter and Setter-->选择属性,自动生成。
package com.first.pojo;
public class Users {
private int userid;
private String username;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
SingleObjectServlet.java:
package com.first.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;
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;
/*
通过JSON格式响应单个对象
*/
@WebServlet("/single.do")
public class SingleObjectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Users对象
Users users=new Users();
users.setUserid(1);
users.setUsername("kd");
//不能通过字符流输出Users对象,
// 要用Jackson的API将Users对象转换为JSON格式的字符串对象
ObjectMapper objectMapper=new ObjectMapper();
//将Users对象转换为JSON格式的字符串对象
String string=objectMapper.writeValueAsString(users);
System.out.println(string);
//设置响应类型为application/json
resp.setContentType("application/json");
PrintWriter pw=resp.getWriter();
pw.println(string);
pw.flush();
pw.close();
}
}
?singleDemo.jsp:
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2022/5/10
Time: 19:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<script>
function btn() {
var xhr=new XMLHttpRequest();
xhr.open("get","single.do");
xhr.send();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4 && xhr.status == 200){
alert(xhr.responseText);
//通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对转换成javascript对象
var obj=JSON.parse(xhr.responseText);
alert(obj.userid+" "+obj.username);
document.getElementById("span").innerHTML=obj.userid+"<br/>"+obj.username;
}
}
}
</script>
</head>
<body>
<h3>JSON格式的单个对象响应</h3>
<hr/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>
运行:
访问:http://localhost:8888/ajaxTest/singleDemo.jsp
点击OK按钮
?
?
五.通过 JSON 格式在响应中传递多个对象
需求:
定义一个
Users
类,包含
userid
、
username
属性。
实例化多个
Users
对象,通过
JSON
格式将
Users
对象响应到客户端浏览器。
将
Users
对象中的数据插入到页面中。
MultipleObjectServlet.java:
package com.first.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;
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;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/multiple.do")
public class MultipleObjectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Users users1=new Users();
users1.setUserid(1);
users1.setUsername("kd");
Users users2=new Users();
users2.setUserid(2);
users2.setUsername("kevin");
//需要将多个对象放到集合中
List<Users> list=new ArrayList<>();
list.add(users1);
list.add(users2);
//通过jackson将List转换为JSON格式的字符串对象
ObjectMapper objectMapper=new ObjectMapper();
String string=objectMapper.writeValueAsString(list);
System.out.println(string);
resp.setContentType("application/json");
PrintWriter pw=resp.getWriter();
pw.println(string);
pw.flush();
pw.close();
}
}
multipleDemo.jsp:
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2022/5/10
Time: 23:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<script>
function btn() {
var xhr=new XMLHttpRequest();
xhr.open("get","multiple.do");
xhr.send();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4 && xhr.status == 200){
alert(xhr.responseText);
//通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对转换成javascript对象
var obj=JSON.parse(xhr.responseText);
var temp="";
for (i=0;i<obj.length;i++){
alert(obj[i].userid+" "+obj[i].username);
}
temp+=obj[i].userid+" "+obj[i].username+"<br/>";
document.getElementById("span").innerHTML=temp;
}
}
}
</script>
</head>
<body>
<h3>JSON格式的多个对象响应</h3>
<hr/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>
Users类先前已经创建。
输出:
访问:http://localhost:8888/ajaxTest/multipleDemo.jsp
?
?
?
?
?六.在 JSON 中通过 Map 传递数据
在
JSON
格式中可以直接使用
Map
作为传递数据的模型。因为
Map
结构本身就是
key与
value
的结构与
JSON
格式对象模型完全匹配,所以我们可以直接将一个
Map
对象转换为
JSON
格式的字符串对象。这对于我们来说是一件非常方便的事情,如果我们返回的数据并
没有对应的模型来存放数据,那么我们可以通过
Map
来解决。
?MapModelServlet.java:
package com.first.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
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;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/map.do")
public class MapModelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//一个Map对象表示的是一个JSON格式的对象
Map<String,Object> map=new HashMap<>();
map.put("userid",1);
map.put("url","map.do");
ObjectMapper objectMapper=new ObjectMapper();
//转换为JSON格式的字符串对象
String string=objectMapper.writeValueAsString(map);
System.out.println(string);
resp.setContentType("application/json");
PrintWriter pw=resp.getWriter();
pw.println(string);
pw.flush();
pw.close();
}
}
?mapDemo.jsp:
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2022/5/11
Time: 14:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<script>
function btn() {
var xhr=new XMLHttpRequest();
xhr.open("get","map.do");
xhr.send();
xhr.onreadystatechange=function () {
if (xhr.readyState == 4 && xhr.status == 200){
alert(xhr.responseText);
//通过javaScript的内置对象JSON中的parse函数将JSON格式的字符串对转换成javascript对象
var obj=JSON.parse(xhr.responseText);
alert(obj.userid+" "+obj.url);
document.getElementById("span").innerHTML=obj.userid+"<br/>"+obj.url;
}
}
}
</script>
</head>
<body>
<h3>在JSON中通过Map传递数据</h3>
<hr/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>
?输出:
访问?http://localhost:8888/ajaxTest/mapDemo.jsp
?
?
?
七.在请求中通过 JSON 格式传递数据
我们除了可以在响应中通过
JSON
格式来传递数据以外,在
请求中
也可以使用
JSON
格式传递数据。如果在请求中使用
JSON
格式传递数据,那么提交方式需要使用
POST 方式
,
通过
JavaScript
中的
JSON.stringify()
函数将
JavaScript
对象转换为
JSON
格式数据。通过
send
方法将参数传递到
Servlet
中,在
Servlet
中通过
字符输入流
获取
JSON
格式数据。
在请求中使用 Jackson 处理 JSON 格式数据的步骤:
- 添加 jackson-annotations.jar、jackson-core.jar、jackson-databind.jar
- 在页面的 JavaScript 中通过 JSON.stringify()函数将 JavaScript 对象转换为 JSON 格式的数据
- 将请求方式修改为 POST 方式
- 通过 send()函数将 JSON 格式的数据提交到服务端。
- 在 Servlet 中通过字符输入流读取请求体中 JSON 格式的数据
- 通过 jackson API 将获取到的 JSON 格式的数据转换为 Java 对象
requestDemo.jsp:
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2022/5/11
Time: 14:44
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<script>
function btn() {
var id=document.getElementById("userid").value;
var name=document.getElementById("username").value;
/*将信息构造成JavaScript对象,因为下面的函数只能对JavaScript对象进行操作
这里的键必须和Users类里的属性名相同,因为servlet里要根据名称构造类对象
*/
var obj={userid:id,username:name};
//将 JavaScript 对象转换为 JSON 格式的数据
var content=JSON.stringify(obj);
alert(content);
var xhr=new XMLHttpRequest();
xhr.open("post","json.do");
//post方式传递请求信息,get时是无参
xhr.send(content);
xhr.onreadystatechange=function () {
if (xhr.readyState == 4 && xhr.status == 200){
alert(xhr.responseText);
document.getElementById("span").innerHTML=xhr.responseText;
}
}
}
</script>
</head>
<body>
<h3>在请求中通过JSON格式传递数据</h3>
<hr/>
用户ID:<input name="userid" id="userid"/><br/>
用户姓名:<input name="username" id="username"/><br/>
<span id="span"></span>
<input type="button" value="OK" onclick="btn()"/>
</body>
</html>
?RequestJSONServlet.java:
package com.first.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;
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("/json.do")
public class RequestJSONServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//防止请求信息中有汉字造成乱码
req.setCharacterEncoding("utf-8");
//通过字符输入流从请求体中获取提交的JSON格式的数据
String s=req.getReader().readLine();
//使用Jackson将JSON格式的字符串对象转换成java对象
ObjectMapper objectMapper=new ObjectMapper();
//根据类模板(第二个参数)来解析json数据生成响应类的对象
Users users=objectMapper.readValue(s,Users.class);
System.out.println(users.getUserid()+" "+users.getUsername());
resp.setContentType("application/json");
PrintWriter pw=resp.getWriter();
pw.println("OK");
pw.flush();
pw.close();
}
}
?输出:
?
?
?
?八.Jackson 的常用注解
1.@JsonProperty
此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把
username
属性序列化为
name
,
@JsonProperty("name")
。
2.@JsonIgnore
此注解用于属性或者方法上(一般都是定义在属性上),用来完全忽略被注解的字段和方法对应的属性,返回的
json
数据即不包含该属性。
此注解用于属性或者方法上(一般都是定义在属性上),可以方便的把
Date 类型属性的值直接转化为我们想要的样式。如:
@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss")
annDemo.jsp:
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2022/5/11
Time: 16:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script>
function btn() {
//创建 XMLHttpRequest 对象
var xhr=new XMLHttpRequest();
//请求一个servlet,这个servlet的url是ajax.do
xhr.open("get","ann.do");
//发送异步请求
xhr.send();
//获取服务器端给客户端的响应数据
//当send函数执行之后,下面的函数立即执行
xhr.onreadystatechange=function () {
//0:open()没有被调用
// 1:open()正在被调用
// 2:send()正在被调用
// 3:服务端正在返回结果
// 4:请求结束,并且服务端已经结束发送数据到客户端
//响应成功
if(xhr.readyState==4 && xhr.status == 200){
//输出服务端返回的内容
alert(xhr.responseText);
//将返回内容放到span标签中
document.getElementById("span").innerHTML=xhr.responseText;
}
}
}
</script>
</head>
<body>
<h3>Jackson 的常用注解</h3>
<hr/>
<span id="span">点击按钮改变</span>
<input type="button" value="ok" onclick="btn()"/>
</body>
</html>
?Users.java:
package com.first.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
public class Users {
@JsonIgnore
private int userid;
/*java对象以json形式输出时,这个键不再是username,而是name
如果是json串转换成Java对象,那么键是name时,对应对象的username
*/
//@JsonIgnore 已经有注解的属性上再加这个属性是使这个属性的其他注解无效
@JsonProperty("name")
private String username;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date userBirth;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getUserBirth() {
return userBirth;
}
public void setUserBirth(Date userBirth) {
this.userBirth = userBirth;
}
}
?AnnotationServlet.java:
package com.first.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.first.pojo.Users;
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;
import java.util.Date;
@WebServlet("/ann.do")
public class AnnotationServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Users users=new Users();
users.setUserid(1);
users.setUsername("kd");
users.setUserBirth(new Date());
ObjectMapper objectMapper=new ObjectMapper();
//将Users对象转换为JSON格式的字符串对象
String string=objectMapper.writeValueAsString(users);
System.out.println(string);
resp.setContentType("application/json");
PrintWriter pw=resp.getWriter();
pw.println("Jackson Annoation");
pw.flush();
pw.close();
}
}
输出:
{"userBirth":"2022-05-11","name":"kd"}
九.Jackson 工具类的使用
创建common文件夹,存放工具类
JsonUtils.java:
package com.first.common;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* JSON转换工具类
*/
public class JsonUtils {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
* <p>Title: pojoToJson</p>
* <p>Description: </p>
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param clazz 对象中的object类型
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
* <p>Title: jsonToList</p>
* <p>Description: </p>
* @param jsonData
* @param beanType
* @return
*/
public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
?上节的?AnnotationServlet.java可做如下修改:
// ObjectMapper objectMapper=new ObjectMapper();
// //将Users对象转换为JSON格式的字符串对象
// String string=objectMapper.writeValueAsString(users);
String string= JsonUtils.objectToJson(users);
System.out.println(string);
可见输出还是一样。
|