springboot从小白到大神 004扯一下前后端分离的事

来源:
每日新闻头条
最后修订:
2017-03-22 08:10:18

摘要:又该上课啦~~~上一节,我们完成了一个Book模块的增删改查共5个接口的开发工作,也提供了测试方法,但是有些刚入门的同学可能还是会有疑问:这个接口做好了有什么用呢,用户的电脑浏览器和手机App怎么使用...

springboot从小白到大神 004扯一下前后端分离的事


又该上课啦~~~

上一节,我们完成了一个Book模块的增删改查共5个接口的开发工作,也提供了测试方法,但是有些刚入门的同学可能还是会有疑问:这个接口做好了有什么用呢,用户的电脑浏览器和手机App怎么使用这些接口呢?他们是怎么实现像postman一样和后台接口的数据交换呢?

咱们这一节就扯扯这个事儿,以下都是按照我自己的理解来说的,欢迎专家们批评指正~~~

网上有很多各种开发语言的教程,大多都会提到了MVC,这是一种设计理念,意思就是说把技术开发分为模型(Model,可以理解为数据),视图(View,可以理解为页面或界面)和控制器(Controller,可以理解为业务或者是数据处理的逻辑)三个部分,这样设计有很多的优点,比如三者之间不会相互影响,在需求有变化的时候对代码的修改量最小等等;

那么问题来了,咱们上一节的例子中,数据是有的,控制器(逻辑)也是有的,不过视图好像没有,怎么缺了一大块呢?

这就引入了咱们今天的主题:前后端分离;

过去,互联网项目没有那么复杂,界面没有那么花哨的时候,单独一个模块交给一个人或一个小组做就ok了,而现在系统越来越庞大,功能越来越复杂,对视图/界面的要求越来越高。。。在这种情况下,前后端分离就出现了,开发人员也随着分为前端和后端两个阵营(当然也有nb的全栈工程师,就是全都能做的),后端就只负责数据和业务逻辑,而前端就专心负责视图,也就是界面和用户交互的工作(这里有UI,UE等等很多概念可以向度娘了解下);

咱们上一节基本完成了Book模块的后端工作,那么对于这个功能模块,当前端做好漂亮的界面之后怎么来跟咱们后端对接呢?下面我们就来做做前端的工作,实际感受一下看看(我是客串的,有说的不对的地方,前端大神们请见谅),let‘s go~~~


在上一节chapter-02项目代码的基础上

新建public文件夹及若干html文件,如下:

springboot从小白到大神 004扯一下前后端分离的事

有人要问了,这些html文件为什么要放在public下呢,据说放在static和templates下面也可以?

这是因为,咱们今天要说的是前后端分离,放在项目的public目录下,sprintboot会把这些文件当做纯静态资源进行处理,或者换句话说,项目不需要再做其他改动(不需要引入thymeleaf或者freemarker或者jsp等),而对这些文件的修改也不会对项目功能有任何影响;你还可以直接把这些实现前端功能的html文件全部拷贝走,放在其他的webserver软件下运行,也能行;

好,下面直接上代码:

  • index.html,这就是个导航页,没啥好说的

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Index</title>

</head>

<body>

<h2>前端测试页面</h2><hr/>

<h3><a href="/findAll.html">获取所有Book</a></h3>

<h3><a href="/findOne.html">获取单个Book</a></h3>

<h3><a href="/add.html">新增Book</a></h3>

<h3><a href="/update.html">修改Book</a></h3>

<h3><a href="/delete.html">删除Book</a></h3>

</body>

</html>

springboot从小白到大神 004扯一下前后端分离的事

  • findAll.html,获取所有Book接口测试(里面用到了3种方式)

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>findAll</title>

<script type="text/javascript">

var xmlhttp;

function findAllByAjax() {

url="/books";

xmlhttp=null;

if (window.XMLHttpRequest) {

// all modern browsers

xmlhttp=new XMLHttpRequest();

} else if (window.ActiveXObject) {

// for IE5, IE6

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

if (xmlhttp!=null){

xmlhttp.onreadystatechange=state_Change;

xmlhttp.open("GET", url, true);

xmlhttp.send(null);

} else {

alert("Your browser does not support XMLHTTP.");

}

}

function state_Change(){

if (xmlhttp.readyState==4) {

// 4 = "loaded"

if (xmlhttp.status==200) {

// 200 = "OK"

document.getElementById('resultData').innerHTML=xmlhttp.responseText;

} else {

alert("Problem retrieving data:" + xmlhttp.statusText);

}

}

}

</script>

</head>

<body>

<h1>1. 获取所有Book接口测试</h1>

<p>GET -- /books</p>

<hr/>

体检参数:<br/>

无~~~

<hr/>

超链接方式:<br/>

<a href="/books">findAll by link</a>

<hr/>

表单方式:<br/>

<form action="/books" method="GET">

<input type="submit" value="findAll by form">

</form>

<hr/>

Ajax方式:<br/>

<button onclick="findAllByAjax()">findAll by Ajax</button><br/>

<textarea id="resultData" rows="15" cols="50">接口返回的数据会显示在这里</textarea>

</body>

</html>

springboot从小白到大神 004扯一下前后端分离的事

  • findOne.html,获取单个Book接口测试(里面用到了两种方式)

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>findOne</title>

<script type="text/javascript">

var xmlhttp;

function findOneByAjax() {

bookId=document.getElementById('book_id').value;

url="/books/" + bookId;

xmlhttp=null;

if (window.XMLHttpRequest) {

// all modern browsers

xmlhttp=new XMLHttpRequest();

} else if (window.ActiveXObject) {

// for IE5, IE6

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

if (xmlhttp!=null){

xmlhttp.onreadystatechange=state_Change;

xmlhttp.open("GET", url, true);

xmlhttp.send(null);

} else {

alert("Your browser does not support XMLHTTP.");

}

}

function state_Change() {

if (xmlhttp.readyState==4) {

// 4 = "loaded"

if (xmlhttp.status==200) {

// 200 = "OK"

document.getElementById('resultData').innerHTML=xmlhttp.responseText;

} else {

alert("Problem retrieving data:" + xmlhttp.statusText);

}

}

}

function submitForm() {

bookId=document.getElementById('book_id').value;

myForm=document.getElementById('test_form');

myForm.action="/books/" + bookId;

myForm.submit();

}

</script>

</head>

<body>

<h1>2. 获取单个Book接口测试</h1>

<p>GET -- /books/xxx</p>

<hr/>

提交参数:<br/>

id:<input type="text" id="book_id" />

<hr/>

表单方式:<br/>

<form action="/books/xxx" method="GET" id="test_form">

<input type="button" value="findOne by form" onclick="submitForm()" />

</form>

<hr/>

Ajax方式:<br/>

<button onclick="findOneByAjax()">findOne by Ajax</button><br/>

<textarea id="resultData" rows="15" cols="50">接口返回的数据会显示在这里</textarea>

</body>

</html>

springboot从小白到大神 004扯一下前后端分离的事

  • add.html,新增Book接口测试(里面用到了两种方式)

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>add</title>

<script type="text/javascript">

var xmlhttp;

function addByAjax() {

bookId=document.getElementById('id').value;

bookName=document.getElementById('name').value;

bookAuthor=document.getElementById('author').value;

bookTotalPage=document.getElementById('totalPage').value;

para="id=" + bookId + "&name=" + bookName + "&author=" + bookAuthor + "&totalPage=" + bookTotalPage;

url="/books";

xmlhttp=null;

if (window.XMLHttpRequest) {

// all modern browsers

xmlhttp=new XMLHttpRequest();

} else if (window.ActiveXObject) {

// for IE5, IE6

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

if (xmlhttp!=null){

xmlhttp.onreadystatechange=state_Change;

xmlhttp.open("POST", url, true);

xmlhttp.setRequestHeader('content-type','application/x-www-form-urlencoded');

xmlhttp.send(para);

} else {

alert("Your browser does not support XMLHTTP.");

}

}

function state_Change() {

if (xmlhttp.readyState==4) {

// 4 = "loaded"

if (xmlhttp.status==200) {

// 200 = "OK"

document.getElementById('resultData').innerHTML=xmlhttp.responseText;

} else {

alert("Problem retrieving data:" + xmlhttp.statusText);

}

}

}

</script>

</head>

<body>

<h1>3. 新增Book接口测试</h1>

<p>POST -- /books</p>

<hr/>

表单方式:<br/>

<form action="/books" method="POST" id="test_form">

提交参数:<br/>

id:<input type="text" name="id" id="id" /><br/>

name:<input type="text" name="name" id="name" /><br/>

author:<input type="text" name="author" id="author" /><br/>

totalPage:<input type="text" name="totalPage" id="totalPage" /><br/>

<br/><br/>

<input type="submit" value="add by form" />

</form>

<hr/>

Ajax方式:<br/>

<button onclick="addByAjax()">add by Ajax</button><br/>

<textarea id="resultData" rows="15" cols="50">接口返回的数据会显示在这里</textarea>

</body>

</html>

springboot从小白到大神 004扯一下前后端分离的事

  • update.html,修改Book接口测试(里面只用到了一种方式)

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>update</title>

<script type="text/javascript">

var xmlhttp;

function updateByAjax() {

oldBookId=document.getElementById('bookId').value;

bookId=document.getElementById('id').value;

bookName=document.getElementById('name').value;

bookAuthor=document.getElementById('author').value;

bookTotalPage=document.getElementById('totalPage').value;

para="id=" + bookId + "&name=" + bookName + "&author=" + bookAuthor + "&totalPage=" + bookTotalPage;

url="/books/" + oldBookId;

xmlhttp=null;

if (window.XMLHttpRequest) {

// all modern browsers

xmlhttp=new XMLHttpRequest();

} else if (window.ActiveXObject) {

// for IE5, IE6

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

if (xmlhttp!=null){

xmlhttp.onreadystatechange=state_Change;

xmlhttp.open("PUT", url, true);

xmlhttp.setRequestHeader('content-type','application/x-www-form-urlencoded');

xmlhttp.send(para);

} else {

alert("Your browser does not support XMLHTTP.");

}

}

function state_Change() {

if (xmlhttp.readyState==4) {

// 4 = "loaded"

if (xmlhttp.status==200) {

// 200 = "OK"

document.getElementById('resultData').innerHTML=xmlhttp.responseText;

} else {

alert("Problem retrieving data:" + xmlhttp.statusText);

}

}

}

function submitForm() {

bookId=document.getElementById('bookId').value;

myForm=document.getElementById('test_form');

myForm.action="/books/" + bookId;

myForm.submit();

}

</script>

</head>

<body>

<h1>4. 修改Book接口测试</h1>

<p>PUT -- /books/xxx</p>

<hr/>

表单方式:<br/>

<form action="/books" method="PUT" id="test_form">

提交参数:<br/>

bookId:<input type="text" name="bookId" id="bookId" /><br/>

id:<input type="text" name="id" id="id" /><br/>

name:<input type="text" name="name" id="name" /><br/>

author:<input type="text" name="author" id="author" /><br/>

totalPage:<input type="text" name="totalPage" id="totalPage" /><br/>

<br/><br/>

<input type="submit" value="update by form(form表单提交PUT和DELETE的method很多浏览器都不支持,我也没测成功,咱们这儿就不试了)" onclick="submitForm()" disabled="disabled" />

</form>

<hr/>

Ajax方式:<br/>

<button onclick="updateByAjax()">update by Ajax</button><br/>

<textarea id="resultData" rows="15" cols="50">接口返回的数据会显示在这里</textarea>

</body>

</html>

springboot从小白到大神 004扯一下前后端分离的事

  • delete.html,删除Book接口测试(里面也只用到了一种方式)

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>delete</title>

<script type="text/javascript">

var xmlhttp;

function deleteByAjax() {

bookId=document.getElementById('bookId').value;

url="/books/" + bookId;

xmlhttp=null;

if (window.XMLHttpRequest) {

// all modern browsers

xmlhttp=new XMLHttpRequest();

} else if (window.ActiveXObject) {

// for IE5, IE6

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

if (xmlhttp!=null){

xmlhttp.onreadystatechange=state_Change;

xmlhttp.open("DELETE", url, true);

xmlhttp.setRequestHeader('content-type','application/x-www-form-urlencoded');

xmlhttp.send();

} else {

alert("Your browser does not support XMLHTTP.");

}

}

function state_Change() {

if (xmlhttp.readyState==4) {

// 4 = "loaded"

if (xmlhttp.status==200) {

// 200 = "OK"

document.getElementById('resultData').innerHTML=xmlhttp.responseText;

} else {

alert("Problem retrieving data:" + xmlhttp.statusText);

}

}

}

function submitForm() {

bookId=document.getElementById('bookId').value;

myForm=document.getElementById('test_form');

myForm.action="/books/" + bookId;

myForm.submit();

}

</script>

</head>

<body>

<h1>5. 删除Book接口测试</h1>

<p>DELETE -- /books/xxx</p>

<hr/>

表单方式:<br/>

<form action="/books" method="DELETE" id="test_form">

提交参数:<br/>

bookId:<input type="text" name="bookId" id="bookId" /><br/>

<br/><br/>

<input type="submit" value="delete by form(form表单提交PUT和DELETE的method很多浏览器都不支持,我也没测成功,咱们这儿就不试了)" onclick="submitForm()" disabled="disabled" />

</form>

<hr/>

Ajax方式:<br/>

<button onclick="deleteByAjax()">delete by Ajax</button><br/>

<textarea id="resultData" rows="15" cols="50">接口返回的数据会显示在这里</textarea>

</body>

</html>

springboot从小白到大神 004扯一下前后端分离的事

真难为情,这些页面着实丑爆了,不过能说明问题,呵呵~

前端开发的工作内容中,页面布局,美化这些工作就不说了,但是前端和后端数据交换的三种方式上面都演示到了,这些就是前端程序猿日常工作内容的一部分;

三种方式中:

1. 超链接的方式最简单,他可以表现为文字,图片,视频等等,点击之后就直接跳转到别的页面;

2. 表单提交的方式也很常见,比如咱们在网站注册用户,论坛发帖、回帖等等,用户在页面输入数据并提交至网站后台,然后跳去其他页面的时候,大多都是采用的这种方式;

3. 最后一种Ajax提交方式,现在的使用也越来越多了,前端通过页面中嵌入的javascript代码来动态获取页面数据、发送至后端接口,然后获取接口返回的数据并以各种方式展现在页面上;

第三种方式和前面两种方式的最大区别就是不会出现页面整体刷新和跳转的情况,而只是页面局部的内容发生变化,大家稍微回想一下微博、网盘。。。有感觉了吧~

还有几点需要说明下:

1.上面的html代码中有大量的重复内容,我是懒得搞了,但前段工程师是必须要处理的,比如把重复的html代码提取成模板,把重复的javascript代码封装成函数/方法等等

2.上面的代码中使用的是原生javascript,实现功能的时候非常繁琐、没有效率;事实上,前端也有很多的框架和类库可以用来大幅度提升开发效率,比如大名鼎鼎的JQuery,Bootstrap等等;如果使用框架的话,上面我写的html和javascript代码会非常精炼,页面效果也会很炫

3.使用表单方式实现PUT和DELETE的提交我没有测试成功,网上资料也是说啥的都有;如果有前端大神了解这方面内容的,也请不吝赐教

好了,今天就是这些内容~~~

老规矩:有任何问题,欢迎留言,也可是直接跟我联系,qq:20668627