JS+SpringBoot:前后端分离

  • 简介
  • Springboot前后端交互
  • 前端(JS)
  • 前端处理JSON字符串
  • 后端(SpringBoot)
  • 前后端交互
  • 拓展
  • @注解
  • 全局配置文件application.properties和application.yml
  • JS的let和var区别
  • 分页
  • 前端
  • 后端
  • 注意


简介

springbootspringboot与ssm

spring boot 默认请求超时时间 springboot请求过程_json


开发时顺序是从下到上,最终实现前后端交互是controller层和前端

运行时顺序是从上到下,最终实现交互

spring

  • 简单粗暴介绍:使用注解的类都是交给spring管理,需要spring实例化出bean对象,这样才能调用对应实例方法处理需求。
  • java网站开发(请求-响应模型):url触发bean然后调用方法从而进行逻辑处理最后返回结果,而框架会根据设置的单例或者多例进行bean的管理。

Springboot前后端交互

原生的 Ajax 请求

1、我们首先要创建 XMLHttpRequest 对象

2、调用 .open 方法设置请求参数

3、调用 send 方法发送请求

4、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。

spring boot 默认请求超时时间 springboot请求过程_json_02

前端(JS)

spring boot 默认请求超时时间 springboot请求过程_JS_03

  • 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字符串。

spring boot 默认请求超时时间 springboot请求过程_json_04


spring boot 默认请求超时时间 springboot请求过程_SpringBoot_05

或者触发fuction方法传递信息再次请求服务器进行处理

spring boot 默认请求超时时间 springboot请求过程_分页_06

JS跨界面session传值,常用于登录信息的保存

spring boot 默认请求超时时间 springboot请求过程_json_07


spring boot 默认请求超时时间 springboot请求过程_JS_08

前端处理JSON字符串

var responseText=xmlhttp.responseText;
            //responseText就是服务器返回的数据
            //我们就可以把这个数据装载到列表当中
            var jsonArr=JSON.parse(responseText);

后端(SpringBoot)

根据springmvc映射规则,处理传回来的参数,并且将查询得到的数据(list,object)转化为JSON字符串,返回到对应的请求界面。

JSONObject.toJSONString();

spring boot 默认请求超时时间 springboot请求过程_xml_09

或者自定义json字符串

spring boot 默认请求超时时间 springboot请求过程_JS_10


spring boot 默认请求超时时间 springboot请求过程_JS_11

前后端交互

spring boot 默认请求超时时间 springboot请求过程_SpringBoot_12

拓展

@注解

  • 简单粗暴介绍:使用注解的类都是交给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

  1. 这个配置文件的作用是修改springboot自动配置的默认值;
    比如修改springboot的端口号。
  2. 以前的配置文件,大多使用的是xml文件,yml是以数据为中心,比json、xml更适合做配置文件。
  3. YAML基本语法:
    1、使用缩进表示层次关系
    2、缩进时不允许使用tab键,只允许使用空格。
    3、缩进的空格数据不重要,只要相同层次的元素左侧对齐即可
    4、大小写敏感
    YAML支持三种数据结构
    1、对象:键值对的集合
    2、数据:一组按次序排列的值
    3、字面量:单个的,不可再分的值
  4. 基本语法
    k:(空格)v:表示一对键值对(空格必须有);
    以空格的缩进来控制层次关系;只要是左对齐的一列数据,都是同一个层次的。
    server: port: 8888
  5. 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]

spring boot 默认请求超时时间 springboot请求过程_xml_13

JS的let和var区别

  1. 作用域不一样,var是函数作用域,而let是块作用域,也就是说,在函数内声明了var,整个函数内都是有效的,比如说在for循环内定义了一个var变量,实际上其在for循环以外也是可以访问的,而let由于是块作用域,所以如果在块作用域内(比如说for循环内)定义的变量,在其外面是不可被访问的,所以let用在for
    (let i; i < n; i++)是一种很推荐的写法
  2. let不能在定义之前访问该变量,但是var是可以得。也就是说,let必须是先定义,再使用,而var先使用后声明也行,只不过直接使用但是没有却没有定义的时候,其值为undefined,这块要注意,这一块很容易出问题,这也是个人认为的let比var更好的地方,至于为啥会有这种区别呢,实际上var有一个变量提升的过程。也就是说,当这个函数的作用域被创建的时候,实际上var定义的变量都会被创建,并且如果此时没有初始化的话,则默认会初始化一个undefined。
  3. 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才能对前端传递的需求进行处理。