1.JSON定义(前后端分离的技术)
是一种轻量级的数据交换格式。
相当于替换了绑定值,不用转发和重定向,
由前端通过JSON转成字符串传给后端,
然后后端通过json字符串的数据再传给前端。
json就是个字符串
没JSON之前:
后端当中传递数据给前端,
一般而言是需要将从数据库中解析出来的数据传递
通过绑定到request对象上并传递给前端
(通过的方式: request,setAttribute(“list”,list) )
这个前提是必须使用重定向或者转发
(这种方式依赖于jsp中的el,jstl表达式)
有JSON之后:
但是,如果在前后端分离的应用场景下,一般在servlet中将list拼接
(转换成)JSON字符串形式传递给前端中的ajax,并被ajax解析到html中。
一般会用原生的拼接或者第三方的json转换工具包去完成,
例如阿里的fastjson,解析性能比较高。
ajax的核心原理
根据data的键值对属性,从页面端传递给后端的输入参数
后端获取前端传递的参数,然后根据业务和数据库
在servlet中将list拼接(转换成)JSON字符串形式
通过json再传到前端success回调函数中
其中:datatype指从后端传递的数据类型是json类型
success里方法的形参data指从后端拼接好的json字符串传递给前端。
2.JSON作用
JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,
然后就可以在函数之间轻松地传递这个字符串,
或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。
这个字符串看起来有点儿古怪,但是 JavaScript 很容易解释它,
而且 JSON 可以表示比"名称 / 值对"更复杂的结构。
例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。
==》简单的说:
- JSON用来在客户端和服务器端转换数据用的。
- JSON的键值对格式容易让js解析
- JSON的键值对格式可以被Ajax中返回函数中被转换或者解析。
3.为什么使用JSON
JSON采用完全独立于语言的文本格式,
这些特性使JSON成为理想的数据交换语言。
易于人阅读和编写,同时也易于机器解析和生成。
==》简单的说:
- 独立于任何语言
- 易于人理解
- 便于机器解析和创建
4.JSON语法(摘录菜鸟教程)
(1)JSON存储语法
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在中括号中)
对象(在大括号中)
null
(2)JSON数字(常用)
JSON 数字可以是整型或者浮点型
{ “age”:30 }
(3)JSON对象(常用)
{ “name”:“kgc” , “pwd”:“23434” }
(4)JSON数组(常用)
[
{ “name”:“菜鸟教程” , “url”:“www.runoob.com” },
{ “name”:“google” , “url”:“www.google.com” },
{ “name”:“微博” , “url”:“www.weibo.com” }
]
4.JSON实战(省略导包)
4.1创建Maven工程,数据库,导入jar包和pom依赖,js类库
4.2创建实体类 Fruit
4.3 BaseDao工具类 BaseDao
4.4 dao/FruitDao、FruitDaoImpl
FruitDao
public interface FruitDao {
List<Fruit> findAll();
}
FruitDaoImpl
public class FruitDaoImpl extends BaseDao implements FruitDao {
@Override
public List<Fruit> findAll() {
List<Fruit> list = new ArrayList<>();
rs = super.executeQuery("select * from t_fruit",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.closeAll();
}
return list;
}
}
4.5 service/ FruitService、FruitServiceImpl
省略
4.6servlet/ FruitServlet
public class FruitServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
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", "*");
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
String action = request.getParameter("action");
FruitServiceImpl fruitService = new FruitServiceImpl();
if (action.equals("list")){
//分支1:利用非JSON方式查询列表
List<Fruit> list = fruitService.findAll();
request.setAttribute("list",list);
request.getRequestDispatcher("list.jsp").forward(request,response);
}else if (action.equals("list2")){
//分支2:创建原生的json数组 \是转义符 不然编译不出来 三个对象
String json = "[{\"fruitId\":\"11\",\"type\":\"apple\",\"breed\":\"aaa\"}," +
"{\"fruitId\":\"22\",\"type\":\"banana\",\"breed\":\"bbb\"}," +
"{\"fruitId\":\"33\",\"type\":\"orange\",\"breed\":\"ooo\"}]";
response.getWriter().print(json);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}else if (action.equals("list3")){
//分支3:创建原生的动态(动态:即从数据库里获取数据)json数组
//迭代测试 进行测试 一步一步来
List<Fruit> list = fruitService.findAll();
StringBuffer sb = new StringBuffer("[");
for (int i = 0; i < list.size(); i++) {
//从数据库中循环遍历出水果记录列表
Fruit fruit = list.get(i);
String json = "{\"fruitId\":\""+fruit.getFruitId()+"\",\"type\":\""+fruit.getType()+"\",\"breed\":\""+fruit.getBreed()+"\"}";
// String json = "{fruitId:"+fruit.getFruitId()+",type:"+fruit.getType()+",breed:"+fruit.getBreed()+"}";
// 遇到前面有\的"就是不把它当成有字符串起始意义的" 字符串常量
sb.append(json);
if (i<list.size()-1){
sb.append(",");
}
}
sb.append("]");
response.getWriter().print(sb);
}else if (action.equals("list4")){
//分支4:
List<Fruit> list = fruitService.findAll();
String json = JSON.toJSONString(list);
response.getWriter().print(json);
}
// Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,
//当然它也可以将 JSON 字符串转换为 Java 对象。
//alibaba fastjson 要导包 依赖包
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
一共有四种方法,最后一种最方便,
但有些公司不会用阿里云的,所以还是会用2.3种。
第一种一般,不用json,也没有前后端分离,并且这个是用servlet访问。
4.7 配置xml
4.8 配置jsp和html
list.jsp 第一种
<%@ 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>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script>
</script>
</head>
<body>
<form>
<table border="1px">
<tr>
<td>水果编码:</td>
<td>水果类型:</td>
<td>水果品种:</td>
</tr>
<c:forEach var="list" items="${list}">
<tr>
<td>${list.fruitId}</td>
<td>${list.type}</td>
<td>${list.breed}</td>
</tr>
</c:forEach>
</table>
</form>
</body>
</html>
list4.jsp 2.3.4种
<%--可以直接调前端 不用调后端 前后端分离 并且不用写html--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script>
$(function(){
$.ajax({
"url":"FruitServlet",
"type":"post",
"data":{"action":"list4"},
"dataType":"json",
"async":false,
"success":function(data) {//从servlet获取 返回值
var $ul = $("table");
$ul.append("<tr><td>水果编号</td><td>水果类型</td><td>水果品种</td><tr>");
for (var i = 0;i<data.length;i++){
$ul.append("<tr><td>"+data[i].fruitId+"</td><td>"+data[i].type+"</td><td>"+data[i].breed+"</td><tr>")
}
// append() 方法在被选元素的结尾插入指定内容。
},
"error":function() {}
});
});
</script>
</head>
<body>
<form>
<table border="1px" style="border-collapse: collapse">
</table>
</form>
</body>
</html>
但jsp是属于Java的
把jsp换成html 再添加html5的格式 所谓的前后端分离
el和jstl是java的前端 前端不懂
但还是不是真正的分离。
真正的前后端分离:
需要让html文件在专门的前端工具
HBuilder X 、 Visual Studio
在前端工具里url必须要 写全地址,并且导js包
但运行可能会报如下问题
No ‘Access-Control-Allow-Origin’ header
is present on the requested resource.
跨域问题:
Java 后端彻底解决跨域问题
跨域是a页面想要获取b页面资源,如果a,b页面的协议、域名、端口号、子域名不同,所进行的访问都是跨域的,而浏览器一般为了安全都限制了跨域访问,也就是不允许跨域访问资源。
解决方法:
在Servlet里把这段代码写上去 就能解决
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", "*");
----2021.11.17&11.18