1.定义:
json是一种轻量级的数据交换格式
Javascript Object Notation
采用完全不同于编程语言的格式来存储和标识数据
2.json作用
json可以将Javascript对象中表示的一组数据转化成字符串,然后就可以在函数之间轻松的传递这个字符串,或者在异步应用程序中将字符串从web客户机传递给服务器端程序,
这个字符串看起来有点儿古怪,但是 JavaScript 很容易解释它,而且 JSON 可以表示比"名称 / 值对"更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表
总结:
json用来在客户端和服务器端转换数据用
json的键值对容易让js解析
json的键值对格式可以在ajax返回函数中被转换或者解析
3.为什么使用json
JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
4.json语法
数字:整数和浮点数 {"age":123}
字符串:双引号中 {"name":"zs"}
逻辑值:true和false {"flag":true}
数组:中括号中 [{"name":"zs"},{"age":123}]
对象:大括号中{"pwd":"123"}
null值:{"pwd":null}
5.json和servlet实现数据交互和前后端分离
创建一个水果数据库,利用servlet和json实现前后端的分离和数据的交互
1.创建数据库
创建表格并添加数据
2.创建实体类:entity/Fruit.java
package cn.kgc.entity;
import java.math.BigDecimal;
public class Fruit {
private Integer fruitId;
private String type;
private String breed;
private String area;
private String brief;
private Integer weight;
private BigDecimal price;
public Fruit() {
}
public Fruit(Integer fruitId, String type, String breed, String area, String brief, Integer weight, BigDecimal price) {
this.fruitId = fruitId;
this.type = type;
this.breed = breed;
this.area = area;
this.brief = brief;
this.weight = weight;
this.price = price;
}
public Integer getFruitId() {
return fruitId;
}
public void setFruitId(Integer fruitId) {
this.fruitId = fruitId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getBrief() {
return brief;
}
public void setBrief(String brief) {
this.brief = brief;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
3.创建dao包中的BaseDao和接口以及实现类
创建BaseDao实现对数据库操作的封装:
package cn.kgc.dao;
import java.sql.*;
public class BaseDao {
//对数据库操作的封装
//预连接对象
protected Connection connection;
//预编译对象
protected PreparedStatement ps;
//结果集对象
protected ResultSet rs;
//四种主要方法:
//1.连接数据库:
public void getConnection(){
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","111");
System.out.println(connection);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
//2.关闭连接
public void closeConnection(){
//先开的后关,对每个对象添加判断
try {
if (rs!=null){
rs.close();
}
if (ps!=null){
ps.close();
}
if(connection!=null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//3.增删改的通用方法
public Integer update(String sql,Object[] params){
//1.获取连接
getConnection();
int a = 0;
try {
//2.发送sql语句
ps = connection.prepareStatement(sql);
if (params!=null){
for (int i = 0; i< params.length;i++){
//3.用setObject()方法补齐sql语句
ps.setObject(i+1,params[i]);
}
}
//4.执行sql
a = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//5.关闭连接
closeConnection();
}
return a;
}
public ResultSet query(String sql,Object[] params){
//1.获取连接
getConnection();
try {
//2.发送sql语句
ps = connection.prepareStatement(sql);
if (params!=null){
for (int i = 0; i< params.length;i++){
//3.用setObject()方法补齐sql语句
ps.setObject(i+1,params[i]);
}
}
//4.执行sql(查询执行的是executeQuery())
rs = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
//注意:不能关闭
return rs;
}
public static void main(String[] args) {
BaseDao baseDao = new BaseDao();
baseDao.getConnection();
}
}
接口:
package cn.kgc.dao;
import cn.kgc.entity.Fruit;
import java.util.List;
public interface FruitDao {
public List<Fruit> findAll();
}
实现类:
package cn.kgc.dao;
import cn.kgc.entity.Fruit;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class FruitDaoImpl extends BaseDao implements FruitDao {
@Override
public List<Fruit> findAll() {
ArrayList<Fruit> list = new ArrayList<>();
rs = super.query("select * from fruit_new", null);
try {
while(rs.next()){
Fruit fruit = new Fruit(rs.getInt("fruitId"), rs.getString("type"),rs.getString("breed"),rs.getString("area"),rs.getString("brief"),rs.getInt("weight"),rs.getBigDecimal("price"));
list.add(fruit);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
super.closeConnection();
}
return list;
}
}
4.创建service层:service/FruitService.java接口和实现类
接口:
package cn.kgc.service;
import cn.kgc.entity.Fruit;
import java.util.List;
public interface FruitService {
public List<Fruit> findAll();
}
实现类:
package cn.kgc.service;
import cn.kgc.dao.FruitDao;
import cn.kgc.dao.FruitDaoImpl;
import cn.kgc.entity.Fruit;
import java.util.List;
public class FruitServiceImpl implements FruitService{
protected FruitDao fruitDao = new FruitDaoImpl();
@Override
public List<Fruit> findAll() {
return fruitDao.findAll();
}
}
5.servlet
package cn.kgc.servlet;
import cn.kgc.entity.Fruit;
import cn.kgc.service.FruitService;
import cn.kgc.service.FruitServiceImpl;
import com.alibaba.fastjson.JSON;
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.util.List;
public class FruitServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置字符集
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获取标识
String action = request.getParameter("action");
FruitService fruitService = new FruitServiceImpl();
//servlet和jsp,jstl,el表达式实现数据传递
if (action.equals("list")) {
List<Fruit> list = fruitService.findAll();
request.setAttribute("list", list);
request.getRequestDispatcher("list.jsp").forward(request, response);
//servlet和json实现数据传递
} else if (action.equals("listJson1")){
List<Fruit> list = fruitService.findAll();
String json = JSON.toJSONString(list);//利用阿里fastjson工具将数据转换为json对象
response.getWriter().print(json);
}
}
}
配置web.xml
6.页面
普通jsp页面:(只展示部分数据)访问servlet页面并带参数
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="">
<table>
<tr>
<td>类别</td>
<td>品种</td>
<td>产地</td>
<td>总重量(公斤)</td>
<td>单价(元/公斤)</td>
<td>操作</td>
</tr>
<c:forEach items="${list}" var="fruit">
<tr>
<td>${fruit.type}</td>
<td>${fruit.breed}</td>
<%-- <td>${fruit.area}</td>--%>
<%-- <td>${fruit.weight}</td>--%>
<%-- <td>${fruit.price}</td>--%>
</tr>
</c:forEach>
</table>
</form>
</body>
</html>
json页面:直接访问jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
$(function () {
$.ajax({
"url": "FruitServlet",
"type": "post",
"data": {"action": "listJson1"},
"dataType": "json",
"async": false,
"success": function (data) {
var $ul = $("table");
$ul.append("<tr><td>水果类型</td><td>水果品种</td></tr>");
for (var i = 0; i <data.length;i++){
// alert(data[i]);
$ul.append("<tr><td>"+data[i].type+"</td><td>"+data[i].breed+"</td></tr>");
}
},
"error": function () {
}
});
});
</script>
</head>
<body>
<form>
<table>
</table>
</form>
</body>
</html>
实现效果:
7.跨域:实现前后端分离:
将jsp页面转为html页面,将url中的绝对路径补齐,除此之外还要对servlet文件中添加跨域的代码:
<html>
<head>
<title>Title</title>
<meta charset="UTF-8">
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
$(function () {
$.ajax({
"url": "http://localhost:8080/FruitServlet", //补齐绝对路径
"type": "post",
"data": {"action": "listJson1"},
"dataType": "json",
"async": false,
"success": function (data) {
var $ul = $("table");
$ul.append("<tr><td>水果类型</td><td>水果品种</td></tr>");
for (var i = 0; i <data.length;i++){
// alert(data[i]);
$ul.append("<tr><td>"+data[i].type+"</td><td>"+data[i].breed+"</td></tr>");
}
},
"error": function () {
}
});
});
</script>
</head>
<body>
<table>
</table>
</body>
</html>
servlet文件中添加:
在方法体的开头添加,然后这个html页面可以放在其他工具中,将tomcat服务器启动,此时直接访问html页面即可得到数据:
//解决跨域
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin,X-Requested-With,Content-Type,Accept,"
+ "content-Type,origin,x-requested-with,content-type,accept,authorization,token,id,X-Custom-Header,X-Cookie,Connection,User-Agent,Cookie,*");
response.setHeader("Access-Control-Request-Headers", "Authorization,Origin, X-Requested-With,content-Type,Accept");
response.setHeader("Access-Control-Expose-Headers", "*");