JS+SpringBoot:前后端分离
- 简介
- Springboot前后端交互
- 前端(JS)
- 前端处理JSON字符串
- 后端(SpringBoot)
- 前后端交互
- 拓展
- @注解
- 全局配置文件application.properties和application.yml
- JS的let和var区别
- 分页
- 前端
- 后端
- 注意
简介
开发时顺序是从下到上,最终实现前后端交互是controller层和前端
运行时顺序是从上到下,最终实现交互
- 简单粗暴介绍:使用注解的类都是交给spring管理,需要spring实例化出bean对象,这样才能调用对应实例方法处理需求。
- java网站开发(请求-响应模型):url触发bean然后调用方法从而进行逻辑处理最后返回结果,而框架会根据设置的单例或者多例进行bean的管理。
Springboot前后端交互
原生的 Ajax 请求
1、我们首先要创建 XMLHttpRequest 对象
2、调用 .open 方法设置请求参数
3、调用 send 方法发送请求
4、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
前端(JS)
- let searchKey= document.getElementById(“searchKey”).value;得到页面输入的值
- Document.getElementById(“id”).innerHTML=tempInnerHtml;设置对应id标签的值和添加标签。
通过使用xmlhttp.open发出请求处理的参数,然后服务器处理完返回JSON字符串,触发xmlhttp.onreadystatechange进行处理。
- xmlhttp.open(“GET”,“course/courseInfo?cid=”+cid,true); xmlhttp.send();
<script>
function loadData(name)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var responseText=xmlhttp.responseText;
//responseText就是服务器返回的数据
//我们就可以把这个数据装载到列表当中
var jsonArr=JSON.parse(responseText);
var mydata=document.getElementById("mydata");
var tempInnerHtml="";
for (let i = 0; i < jsonArr.length; i++) {
tempInnerHtml+=" <tr><td>"+jsonArr[i].cid+"</td>\n" +
" <td>"+jsonArr[i].cname+"</td>\n" +
" <td>"+jsonArr[i].cteacher+"</td>\n" +
" <td>"+jsonArr[i].cnum+"</td>\n" +
" <td>"+jsonArr[i].cused+"</td>\n" +
// " <td><a href='#' οnclick='return onEditClick("+jsonArr[i].id+","+jsonArr[i].tid+","+jsonArr[i].score+",\""+jsonArr[i].time+"\","+jsonArr[i].orderIndex+");'>编辑</a></td>\n" +
" <td><a href='#' οnclick='return onChooseClick("+id+","+jsonArr[i].cid+");'>选择此课程</a></td></tr>";
}
// innerHTML来进行界面的赋值
mydata.innerHTML=tempInnerHtml;
}
}
xmlhttp.open("GET","course/courseInfo",true);
xmlhttp.send();
}
</script>
- <a>标签中,GET方式传递数据类型,href=“+num+”,\””+name+”\”传递参数类型不同,格式也不同
注意:xmlhttp.send()请求一次,服务器响应一次返回处理的参数,同一个xmlhttp.readstatechange函数也触发接收一次服务器返回的JSON字符串。
或者触发fuction方法传递信息再次请求服务器进行处理
JS跨界面session传值,常用于登录信息的保存
前端处理JSON字符串
var responseText=xmlhttp.responseText;
//responseText就是服务器返回的数据
//我们就可以把这个数据装载到列表当中
var jsonArr=JSON.parse(responseText);
后端(SpringBoot)
根据springmvc映射规则,处理传回来的参数,并且将查询得到的数据(list,object)转化为JSON字符串,返回到对应的请求界面。
JSONObject.toJSONString();
或者自定义json字符串
前后端交互
拓展
@注解
- 简单粗暴介绍:使用注解的类都是交给spring管理,需要spring实例化出bean对象,这样才能调用对应实例方法处理前端需求。
spring中的bean都是项目装配启动时要实例化的bean,这样才能使用bean调用实例化方法提供服务。 - 任何框架都是先运行配置文件,该实例化实例化,该注入注入,该配置配置之后再通过前端触发进行使用,凡是所写类只有实例化才能使用对应的实例方法。
- 只有spring可以使用注解进行实例化bean,其余框架都需要基于spring(被spring整合)才能使用注解,而使用注解的类都要在项目装配启动时实例化然后提供服务。
- java网站开发(请求-响应模型):url触发Controllerbean然后调用实例方法从而进行逻辑处理最后返回结果,而框架会根据设置的单例或者多例进行bean的管理。
例如:
@controller,只有项目启动时提前实例化bean才能对前端传递的需求进行处理。
全局配置文件application.properties和application.yml
所有类都需要实例化后才能使用其实例方法,因此全局配置文件是配置的项目会由spring自动实例化的功能类的参数来实现对应配置功能。
- 全局配置文件只能用于配置项目启动时由spring自动实例化的功能类参数来实现对应配置功能等等
- 配置外部插件需要使用配置类来实例化对应的插件类。
SpringBoot使用一个全局的配置文件,配置文件名是固定的。
application.properties。
二者作用相同,都是配置全局,只是代码格式不同。
application.yml。
- 这个配置文件的作用是修改springboot自动配置的默认值;
比如修改springboot的端口号。 - 以前的配置文件,大多使用的是xml文件,yml是以数据为中心,比json、xml更适合做配置文件。
- YAML基本语法:
1、使用缩进表示层次关系
2、缩进时不允许使用tab键,只允许使用空格。
3、缩进的空格数据不重要,只要相同层次的元素左侧对齐即可
4、大小写敏感
YAML支持三种数据结构
1、对象:键值对的集合
2、数据:一组按次序排列的值
3、字面量:单个的,不可再分的值 - 基本语法
k:(空格)v:表示一对键值对(空格必须有);
以空格的缩进来控制层次关系;只要是左对齐的一列数据,都是同一个层次的。
server: port: 8888 - yml值的写法包括字面量:不同的值(数字,字符串,布尔)
k: v:字面量直接来写;字符串默认需用加上单引号或者双引号。
对象、Map(属性和值):
对象还是k:v的方式。在下一行来写对象的属性的值的关系;注意缩进。
friends:
lastName:zhangsan
age:20
行内的写法:friends: {lastName: zhangsan,age: 18}
数组(List、Set):
用- 值表示数组中的一个元素。
pets:
- cat
- dog
- pig
行内写法
pets: [cat,dog,pig]
JS的let和var区别
- 作用域不一样,var是函数作用域,而let是块作用域,也就是说,在函数内声明了var,整个函数内都是有效的,比如说在for循环内定义了一个var变量,实际上其在for循环以外也是可以访问的,而let由于是块作用域,所以如果在块作用域内(比如说for循环内)定义的变量,在其外面是不可被访问的,所以let用在for
(let i; i < n; i++)是一种很推荐的写法 - let不能在定义之前访问该变量,但是var是可以得。也就是说,let必须是先定义,再使用,而var先使用后声明也行,只不过直接使用但是没有却没有定义的时候,其值为undefined,这块要注意,这一块很容易出问题,这也是个人认为的let比var更好的地方,至于为啥会有这种区别呢,实际上var有一个变量提升的过程。也就是说,当这个函数的作用域被创建的时候,实际上var定义的变量都会被创建,并且如果此时没有初始化的话,则默认会初始化一个undefined。
- let不能被重新定义,但是var是可以的。这个呢,我个人认为,从规范化的角度来说,是更推荐的,比如说,你在前面声明了一个变量,后来写代码,因为忘了之前的代码逻辑,又声明了一个同名的变量,如果这俩变量逻辑不一样,并且后面都要用的话,很容易出问题,且不容易维护。
总之呢,let从规范化的角度来说,要比var要进步了很大一步。所以一般情况下的话,推荐用let,const这些。当然啦,如果相对var,const和let有更深入的了解,推荐几篇小文章,这样你就会对其相关知识点有更加深入的了解了。Javascript基础之-var
分页
前端
首先
pageCount = count/PAGE_SIZE+(count%PAGE_SIZE==0?0:1)
计算出来总共的数据页码
然后传回前端使用ul将页码展示出来。
默认loadData(pageNo)加载第一页数据
然后根据点击的页码或者上下页触发传递对应的参数然后进行查询,然后进行局部(对应请求接收处)更新。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>student</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h1 id="banner"></h1>
<a href="stuinfo.html"><button>管理已选课程</button></a>
<!-- 分页栏 处理下标的分页目录-->
<script type="text/javascript">
let pageNo=1;
var pageCount=0;
function loadPageCount(){
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var responseText=xmlhttp.responseText;
pageCount=JSON.parse(responseText);
var tempInnerHTML="<li><a href=\"#\" οnclick='return goPagePrev();'>上一页</a></li>";
for (let i = 0; i < pageCount; i++) {
tempInnerHTML+=" <li><a href=\"#\" οnclick='return onPageClick("+(i+1)+");'>"+(i+1)+"</a></li>";
}
tempInnerHTML+="<li><a href=\"#\" οnclick='return goPageNext();'>下一页</a></li>";
document.getElementById("pagenos").innerHTML=tempInnerHTML;
}
}
xmlhttp.open("GET","course/pageCount",true);
xmlhttp.send();
}
function onPageClick(index){
pageNo=index;
loadData(pageNo);
return false;
}
function goPagePrev(){
if(pageNo==1){
return false;
}
else{
pageNo--;
loadData(pageNo);
}
return false;
}
function goPageNext(){
if(pageNo==pageCount){
return false;
}
else{
pageNo++;
loadData(pageNo);
}
return false;
}
loadPageCount();
</script>
<script>
let name=sessionStorage.getItem("name");
let id=sessionStorage.getItem("id");
let banner=document.getElementById("banner");
banner.innerText="欢迎"+name+"选课";
loadData(1);
function loadData(pageNO)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var responseText=xmlhttp.responseText;
//responseText就是服务器返回的数据
//我们就可以把这个数据装载到列表当中
var jsonArr=JSON.parse(responseText);
var mydata=document.getElementById("mydata");
var tempInnerHtml="";
for (let i = 0; i < jsonArr.length; i++) {
tempInnerHtml+=" <tr><td>"+jsonArr[i].cid+"</td>\n" +
" <td>"+jsonArr[i].cname+"</td>\n" +
" <td>"+jsonArr[i].cteacher+"</td>\n" +
" <td>"+jsonArr[i].cnum+"</td>\n" +
" <td>"+jsonArr[i].cused+"</td>\n" +
// " <td><a href='#' οnclick='return onEditClick("+jsonArr[i].id+","+jsonArr[i].tid+","+jsonArr[i].score+",\""+jsonArr[i].time+"\","+jsonArr[i].orderIndex+");'>编辑</a></td>\n" +
" <td><a href='#' οnclick='return onChooseClick("+id+","+jsonArr[i].cid+");'>选择此课程</a></td></tr>";
}
// innerHTML来进行界面的赋值
mydata.innerHTML=tempInnerHtml;
}
}
xmlhttp.open("GET","course/courseInfo?pageNo="+pageNO,true);
xmlhttp.send();
}
function onChooseClick(sid,cid){
// alert(sid);
// alert(name);
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
//页面刷新
pageNo=1;
document.getElementById("banner").innerHTML=name;
var responseText=xmlhttp.responseText;
//responseText就是服务器返回的数据
//我们就可以把这个数据装载到列表当中
var jsonArr=JSON.parse(responseText);
if(jsonArr=="此课已存在")alert("此课已存在");
else if(jsonArr=="此课加入课表")alert("此课加入课表");
else alert("已课满");
loadData(name);
}
}
xmlhttp.open("GET","cpojo/addInfo?sid="+sid+"&cid="+cid,true);
xmlhttp.send();
}
</script>
<table class="table">
<thead>
<tr>
<th>
课程号
</th>
<th>
课程名
</th>
<th>
授课老师
</th>
<th>
教室容量
</th>
<th>
当前选课人数
</th>
<th>
选择这门课
</th>
</tr>
</thead>
<tbody id="mydata">
</tbody>
</table>
<ul class="pagination" id="pagenos">
</ul>
</body>
</html>
后端
SQL语句
<select id="findCourseByPage" resultMap="courseByPage">
Select *
from course
limit #{pageStart},#{pageSize};
</select>
Service
@Override
public List<Course> findCourseByPage(Integer pageNo) {
return courseDao.findCourseByPage((pageNo-1)*5,5);
}
注意
Js中非xmlhttp.onreadystatechange方法,只在加载或刷新的时候执行一次,而该方法只在服务器响应返回JSON字符串的时候触发。
- 简单粗暴介绍:使用注解的类都是交给spring管理,需要spring实例化出bean对象,这样才能调用对应实例方法处理需求。
spring中的bean都是项目装配启动时要实例化的bean,这样才能使用bean调用实例化方法提供服务。 - 任何框架都是先运行配置文件,该实例化实例化,该注入注入,改配置配置之后再通过触发进行使用,凡是所写类只有实例化才能使用对应的实例方法。
- 只有spring可以使用注解进行实例化bean,其余框架都需要基于spring(被spring整合)才能使用注解,而使用注解的类都要在项目装配启动时实例化然后提供服务。
- java网站开发(请求-响应模型):url触发bean然后调用方法从而进行逻辑处理最后返回结果,而框架会根据设置的单例或者多例进行bean的管理。
例如:
@controller,只有项目启动时提前实例化bean才能对前端传递的需求进行处理。