前言
一位小妹去面试前端,前端leader问了"什么是ajax?",答:“接收后台的数据,然后然后自己填充和渲染样式”;一位小哥去面试后台,技术经理问了“什么是ajax?”,答:“在不需重新加载整个网页的情况下,发送异步请求,返回json数据给前端”。准确答案到底是什么?Ajax到底属于前端还是属于后端?前端(或者后端)到底需不需要懂得Ajax?Ajax请求与普通的http请求有什么区别?数据库中的数据通过Ajax请求和普通请求下分别是怎么传递到前台的...等等一些问题,似乎需要静下心来理一理。
MVC篇
最典型的MVC就是JSP + servlet + javabean的模式,不少人的web起点应该也是这个,记得当时看到最多的问题就是JSP和Servlet区别,后来随着Struts 、Spring MVC等框架出来,MVC被谈论的更多了,越来越多的人开始想要深入学习和理解它,同时也有越来越多的问题开始围绕MVC展开。基本的概念:MVC = Model View Controller = 模型-视图-控制器,太过于概念化的东西确实不太好理解,也许框架都用了好几年,一问MVC还是会懵。不过还是Talk is cheap,下面以Spring MVC + jsp的开发过程示例,同时也是数据在普通http请求后从数据库传递到前端的过程。
背景:ssm项目中,将数据库中TBL_PERSON表的记录全部获取,在前端以表格呈现出来,即<table>标签下(因为自己写的样式实在太丑,重点关注过程吧)
1.Controller层关键代码
package com.mmm.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.mmm.pojo.Person;
import com.mmm.service.PersonService;
@Controller
@RequestMapping("person")
public class PersonController {
@Autowired
PersonService personService;
/**
* 框架跳转页面默认是forward,也就是请求转发
* 这里的model设置的属性,在jsp页面也能直接通过el表达式获取
* */
@RequestMapping(value="httplist")
public String httplist(Model model) {
List<Person> list = personService.selectAll();
model.addAttribute("list", list);
return "person/list";
}
......
}
2.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Person列表</title>
</head>
<body>
<table>
<tr>
<th>姓名</th>
<th>性别</th>
</tr>
<c:forEach var="i" begin="0" end="${list.size() }">
<tr>
<td>${list[i].name }</td>
<td>${list[i].gender }</td>
</tr>
</c:forEach>
</table>
</body>
</html>
3.tomcat启动项目,地址栏输入http://localhost:8081/mm-web/person/httplist,即可看到如下页面,获取到了数据库中完整数据
Ajax篇
传统web开发在没有应用Ajax技术的时候,往往页面是用jsp,而这也让我们看到MVC的不足,视图与控制器间的过于紧密的连接,每次请求必须经过“控制器->模型->视图”这个流程,当java脚本 + 各种表达式 + html代码 +javascript代码混杂一块的时候,简直痛不欲生,代码可读性十分差,而且给后面维护和修改代码的人带来很大阻碍。再说下Ajax,首先简单介绍下,Ajax = 异步 Javascript 和 XML,听名字不难发现,并未涉及到后端java代码,核心对象XMLHTTPRequest(可扩展超文本传输请求),通过它,我们可以在不刷新页面的情况下,发送异步请求至后台,并获取后台返回的json数据。说的简单点,就是不刷新或者跳转页面,发送请求然后拿数据,在这里,比较重要的一点,主动权是在前台这边,前台拿到数据后再根据需求去填充数据内容,渲染样式,实现页面效果。而且由于Ajax基于的Javascript属于前端脚本,并不依赖于jsp环境,页面写Html也是可以的。所以下面以Spring MVC + Ajax + jsp示例(这里的ajax采用Jquery写法,工作中一般也是应用Jquery较多,原生js写法相较繁琐一点,这里就不展示了),同时为了区别返回json数据和直接跳转页面的区别,在控制器中写了两个方法,一个用于跳转页面,但并未拿到数据,等页面载入后,通过js发起Ajax请求到控制层拿到数据,再动态填充到页面,并且无需刷新页面,所以后面我们在地址栏输入地址后,看上去像一次请求,其实一共两次。
1.Controller层关键代码
package com.mmm.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.mmm.pojo.Person;
import com.mmm.service.PersonService;
@Controller
@RequestMapping("person")
public class PersonController {
@Autowired
PersonService personService;
/**
* 这里接受地址栏请求,仅起到转发页面作用,并未传递到我们数据库的内容
* */
@RequestMapping(value="toPage")
public String httplist() {
return "person/list";
}
/**
* 这里@ResponseBody代表该方法接受请求后不是跳转页面,而是直接返回json数据
* 注意引入json相关jar包,还有spring MVC配置中不要漏掉<mvc:annotation-driven/>
* */
@RequestMapping(value="ajaxlist")
@ResponseBody
public List<Person> ajaxlist() {
List<Person> list = personService.selectAll();
return list;
}
......
}
2.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Person列表</title>
<!-- 引入Jquery -->
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<!-- 编写脚本 -->
<script type="text/javascript">
$(function() {
$.ajax({
url: '${pageContext.request.contextPath}/person/ajaxlist',
type: 'post',
dataType: 'json',
success: function(data) {//这里的data代表的就是返回person集合list
var html = "";
html += "<tr><th>姓名</th><th>性别</th></tr>";
for(var i in data){
html += "<tr><td>"+data[i].name+"</td><td>"+data[i].gender+"</td></tr>";
}
$("table").html(html);
}
});
});
</script>
</head>
<body>
<table>
</table>
</body>
</html>
3.tomcat启动项目,地址栏输入http://localhost:8081/mm-web/person/toPage,即可看到如下页面,同样获取到了数据库中完整数据(是两次请求)
关于前后端分离
[如下图所示]。后台有一个对象转化为json的过程,反过来,json传递到前端后,应该有一个内容解析/解读的过程,要知道哪个键对应的值是代表什么含义,该怎么处理。最后,关于AJax到底属于前端还是后端,个人理解是,使用的前端技术,但主要目的是作用于前后端数据交互(请求--获取--处理的过程),然后到底前后端谁该懂得Ajax的问题,觉得只要想想自己作为前端/后端完全不懂这个的话会不会对自己形成障碍,就有自己的答案了。
小结
应用传统的web开发模式,成熟的框架逐步在完善,不过绝大部分框架都是针对前端或者后端,前端层出不穷的样式插件模板,后台不断更新的数据操作和技术选型,但是针对前后端交互的部分,个人觉得还有很大的提升空间。以Jsp为例,熟悉前端的(全栈?)后台开发人员操作起来会相较方便,虽然他的杂合前后端代码广受诟病,但是事实是,Jsp仍然有许多项目是采用的Jsp开发。html + Ajax + js有许多优秀的性质,也还有很多需要完善的地方。目前Ajax应用的已经比较广泛了,所以项目中往往会有两种请求混杂的情况(比较直观就是我们应用Spring MVC时,控制层里的方法,有的加了@Responsebody注解,有的则没有),可以根据项目的需要决定是否采用。
作 者 : young-z