提问:当前所编写的前端代码只适用与B/S架构中,当安卓用户和IOS用户也想访问这些数据时该怎么办?
答:让服务器将数据进行JSON化处理(JSON是各种客户端都能进行接收的数据格式)
因为要将数据专为JSON 格式,所以要引入jack son的jar 包
<!-- 将返回的数据封装成JSON格式 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
EmployeeController:
package com.jy.crud.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jy.crud.bean.Employee;
import com.jy.crud.service.EmployeeService;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@RequestMapping("/emps")
@ResponseBody
public PageInfo getEmpsWithJson(@RequestParam(value = "pn",defaultValue = "1") Integer pageNum){
//引入PageHelper 来进行分页查询
//如何使用?
//在查询之前只需要调用startPage
//第一个参数:从第几页开始查
//第二个参数:一页有几条数据
PageHelper.startPage(pageNum,5);
//startPage 后面紧跟的查询就是分页查询
List<Employee> all = employeeService.getAll();
//使用PageInfo 包装查询后的结果,然后将它返回给list.jsp就行了
//5 : 页面导航区中需要连续显示的页数
PageInfo<Employee> page = new PageInfo<>(all,5);
return page;
}
关于@ResponseBody:
@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML
数据,需要注意的呢,在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
代码说明:
@RequestMapping("/login")
@ResponseBody
public User login(User user){
return user;
}
User字段:userName pwd
那么在前台接收到的数据为:’{“userName”:“xxx”,“pwd”:“xxx”}’
效果等同于如下代码:
@RequestMapping("/login")
public void login(User user, HttpServletResponse response){
response.getWriter.write(JSONObject.fromObject(user).toString());
}
请求页面返回的数据就会变成这样:
Controller 返回PageInfo 对象,该对象不具有通用性。比如:在客户端进行增删改的时候该对象并没有对这三者的状态进行保存,所以客户端是不清楚当前操作是否正确或者完成,所以就要设计一个通用的,带有状态和数据信息的类
package com.jy.crud.bean;
import java.util.HashMap;
import java.util.Map;
/**
* 这是一个通用的类
*/
public class Msg {
//状态码 100-成功 200-失败
private int code;
//提示信息
private String msg;
//用户要返回给浏览器的数据
private Map<String, Object> extend = new HashMap<String, Object>();
public static Msg success(){
Msg result = new Msg();
result.setCode(100);
result.setMsg("处理成功!");
return result;
}
public static Msg fail(){
Msg result = new Msg();
result.setCode(200);
result.setMsg("处理失败!");
return result;
}
public Msg add(String key,Object value){
this.getExtend().put(key, value);
return this;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Map<String, Object> getExtend() {
return extend;
}
public void setExtend(Map<String, Object> extend) {
this.extend = extend;
}
}
Controller 的方法就只用返回Msg:
package com.jy.crud.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jy.crud.bean.Employee;
import com.jy.crud.bean.Msg;
import com.jy.crud.service.EmployeeService;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@RequestMapping("/emps")
@ResponseBody
public Msg getEmpsWithJson(@RequestParam(value = "pn",defaultValue = "1") Integer pageNum){
//引入PageHelper 来进行分页查询
//如何使用?
//在查询之前只需要调用startPage
//第一个参数:从第几页开始查
//第二个参数:一页有几条数据
PageHelper.startPage(pageNum,5);
//startPage 后面紧跟的查询就是分页查询
List<Employee> all = employeeService.getAll();
//使用PageInfo 包装查询后的结果,然后将它返回给list.jsp就行了
//5 : 页面导航区中需要连续显示的页数
PageInfo<Employee> page = new PageInfo<>(all,5);
return Msg.success().add("pageInfo",page);
}
那么现在的请求过程就不是: 访问index.jsp -> index.jsp 发送请求给Controller -> Controller 将请求数据返回给list.jsp
而是:访问index.jsp -> index.jsp 通过JS 发送Ajax 请求 -> Ajax 请求通过Controller 要到分页的数据(Msg) -> index.jsp 的JS 对象获取到Msg,然后解析JSON 数据
<%--
Created by IntelliJ IDEA.
User: Hasee
Date: 2020/8/13
Time: 17:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>
<%--因为要显示的数据是需要遍历出来的,所以就要用到c:foreach标签--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>员工列表</title>
<%
pageContext.setAttribute("APP_PATH",request.getContextPath());
%>
<script type="text/javascript" src="${APP_PATH}/static/js/jquery-1.12.4.min.js"></script>
<%--引入样式--%>
<link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<%--搭建显示页面--%>
<div class="container">
<%--第一列:标题--%>
<div class="row">
<%--12 : 总共有12列,再用占12列--%>
<div class="col-md-12">
<h1>SSM-CRUD</h1>
</div>
</div>
<%--第二列:新增,删除按钮--%>
<div class="row">
<%--这个div占领了4列(col-md-4),又偏移了8列(col-md-offset-8)--%>
<div class="col-md-4 col-md-offset-8">
<%--btn btn-primary: 蓝色, btn btn-dangger: 红色--%>
<button class="btn btn-primary">新增</button>
<button class="btn btn-dangger">删除</button>
</div>
</div>
<%--显示信息--%>
<div class="row">
<%--第三列:显示数据--%>
<div class="col-md-12">
<%--让表格拥有间隔并且鼠标悬停到表格的每一行数据上会有阴影效果--%>
<table class="table table-hover" id="emps_table">
<thead>
<tr>
<th>#</th>
<th>empName</th>
<th>gender</th>
<th>email</th>
<th>deptName</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<%--显示分页信息--%>
<div class="row">
<%--分页文字信息--%>
<div class="col-md-6">
当前页,总共页,总共记录数
</div>
<%--分页条(页码导航)信息--%>
<div class="col-md-6">
</div>
</div>
</div>
<script type="text/javascript">
/*1. 页面加载完成以后, 直接去发送一个ajax 请求,要到分页数据*/
$(function(){
$.ajax({
url:"${APP_PATH}/emps",
data:"pn=1",
type:"get",
success:function (result) {
//请求成功以后(已经通过Controller 拿到了数据),开始解析JSON
//1. 解析出员工数据并显示
build_emps_table(result);
//2. 解析并显示分页信息
}
});
});
/*该函数用于构建员工数据信息的列表*/
function build_emps_table(result) {
/*先获取到Msg(result) 中的extend 下的list*/
var emps = result.extend.pageInfo.list;
//emps: 需要遍历的对象
//function(index,item){...} : 遍历emps时需要执行的回调函数
//index: emps中数据的索引, item: emps遍历出来的数据
$.each(emps,function (index,item) {
var empIdTd = $("<td></td>").append(item.empId);
var empNameId = $("<td></td>").append(item.empName);
var genderId = $("<td></td>").append(item.gender == 'M'?"男":"女");
var emailId = $("<td></td>").append(item.email);
var deptNameId = $("<td></td>").append(item.department.deptName);
//每行数据都有的"编辑"和"删除"按钮
var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑");
var deleteBtn = $("<button></button>").addClass("btn btn-dangger btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
var btn = $("<td></td>").append(editBtn).append(" ").append(deleteBtn); //将"编辑"和"删除"单元格合并到一个<td></td> 中,然后中间留空格
$("<tr></tr>").append(empIdTd).append(empNameId).append(genderId).append(emailId).append(deptNameId).append(btn)
.appendTo("#emps_table tbody"); //这个apppendTo(..):代表将this 添加到目标对象(""#emps_table tbody"")中
});
}
function build_page_nav(result){
}
</script>
</body>
</html>
关于$.each(…) 的运用:
效果图:
开始设置分页记录数和导航栏数据
<%--
Created by IntelliJ IDEA.
User: Hasee
Date: 2020/8/13
Time: 17:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false"%>
<%--因为要显示的数据是需要遍历出来的,所以就要用到c:foreach标签--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>员工列表</title>
<%
pageContext.setAttribute("APP_PATH",request.getContextPath());
%>
<script type="text/javascript" src="${APP_PATH}/static/js/jquery-1.12.4.min.js"></script>
<%--引入样式--%>
<link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<%--搭建显示页面--%>
<div class="container">
<%--第一列:标题--%>
<div class="row">
<%--12 : 总共有12列,再用占12列--%>
<div class="col-md-12">
<h1>SSM-CRUD</h1>
</div>
</div>
<%--第二列:新增,删除按钮--%>
<div class="row">
<%--这个div占领了4列(col-md-4),又偏移了8列(col-md-offset-8)--%>
<div class="col-md-4 col-md-offset-8">
<%--btn btn-primary: 蓝色, btn btn-dangger: 红色--%>
<button class="btn btn-primary">新增</button>
<button class="btn btn-dangger">删除</button>
</div>
</div>
<%--显示信息--%>
<div class="row">
<%--第三列:显示数据--%>
<div class="col-md-12">
<%--让表格拥有间隔并且鼠标悬停到表格的每一行数据上会有阴影效果--%>
<table class="table table-hover" id="emps_table">
<thead>
<tr>
<th>#</th>
<th>empName</th>
<th>gender</th>
<th>email</th>
<th>deptName</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<%--显示分页信息--%>
<div class="row">
<%--分页文字信息--%>
<div class="col-md-6" id="page_info_area">
当前页,总共页,总共记录数
</div>
<%--分页条(页码导航)信息--%>
<div class="col-md-6" id="page_nav_area">
</div>
</div>
</div>
<script type="text/javascript">
/*1. 页面加载完成以后, 直接去发送一个ajax 请求,要到分页数据*/
$(function(){
//一进入页面就去第一页
to_page(1);
});
//因为后面还有点击其他按钮,所以就写一个通用的ajax请求
function to_page(pn){
$.ajax({
url:"${APP_PATH}/emps",
data:"pn="+pn,
type:"get",
success:function (result) {
//请求成功以后(已经通过Controller 拿到了数据),开始解析JSON
//1. 解析出员工数据并显示
build_emps_table(result);
//2. 解析并显示分页信息
build_page_info(result);
build_page_nav(result)
}
});
}
/*该函数用于构建员工数据信息的列表*/
function build_emps_table(result) {
//构建table 之前都先清空table里面的数据,以防与上次的数据叠加
$("#emps_table tbody").empty();
/*先获取到Msg(result) 中的extend 下的list*/
var emps = result.extend.pageInfo.list;
//emps: 需要遍历的对象
//function(index,item){...} : 遍历emps时需要执行的回调函数
//index: emps中数据的索引, item: emps遍历出来的数据
$.each(emps,function (index,item) {
var empIdTd = $("<td></td>").append(item.empId);
var empNameId = $("<td></td>").append(item.empName);
var genderId = $("<td></td>").append(item.gender == 'M'?"男":"女");
var emailId = $("<td></td>").append(item.email);
var deptNameId = $("<td></td>").append(item.department.deptName);
//每行数据都有的"编辑"和"删除"按钮
var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑");
var deleteBtn = $("<button></button>").addClass("btn btn-dangger btn-sm").append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
var btn = $("<td></td>").append(editBtn).append(" ").append(deleteBtn); //将"编辑"和"删除"单元格合并到一个<td></td> 中,然后中间留空格
$("<tr></tr>").append(empIdTd).append(empNameId).append(genderId).append(emailId).append(deptNameId).append(btn)
.appendTo("#emps_table tbody"); //这个apppendTo(..):代表将this 添加到目标对象(""#emps_table tbody"")中
});
}
//解析显示分页信息(总记录数,共有几页...)
function build_page_info(result){
$("#page_info_area").empty();
$("#page_info_area").append("当前"+result.extend.pageInfo.pageNum+"页,总"+result.extend.pageInfo.pages+"页,总"+result.extend.pageInfo.total+"条记录数");
}
//解析显示分页导航条,并且点击分页跳的按键能去到目标页
function build_page_nav(result){
//每一次的请求都要先清空上一次的数据
$("#page_info_area").empty();
//创建按键元素
var ul = $("<ul></ul>").addClass("pagination");
//首页键
var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#"));
//上一页键
var prePageLi = $("<li></li>").append($("<a></a>").append("«"));
//判断如果当前已经在第一页,就不能点击首页和上一页按键
if(result.extend.pageInfo.hasPreviousPage == false){
firstPageLi.addClass("disabled");
prePageLi.addClass("disabled");
}else{
//为"首页""前一页"添加点击翻页事件
firstPageLi.click(function(){
to_page(1);
});
prePageLi.click(function(){
to_page(result.extend.pageInfo.pageNum - 1);
});
}
//下一页键
var NextPageLi = $("<li></li>").append($("<a></a>").append("»"));
//末页键
var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#"));
//判断如果当前已经在最后一页,就不能点击末页和下一页按键
if(result.extend.pageInfo.hasNextPage == false){
NextPageLi.addClass("disabled");
lastPageLi.addClass("disabled");
}else{
//为"末页""下一页"添加点击翻页事件
NextPageLi.click(function(){
to_page(result.extend.pageInfo.pageNum + 1);
});
lastPageLi.click(function(){
to_page(result.extend.pageInfo.pages);
});
}
ul.append(firstPageLi).append(prePageLi);
//中间还需要连续的5页数据
//然后将按键进行高亮显示
$.each(result.extend.pageInfo.navigatePage,function(index,item){
var numLi = $("<li></li>").append($("<a></a>").append(item));
if(result.extend.pageInfo.navigatePage == item){
numLi.addClass("active");
}
//为页码导航键添加事件,用于发ajax请求
numLi.click(function(){
to_page(item);
});
ul.append(numLi);
});
ul.append(NextPageLi).append(lastPageLi);
//把ul 加入到nav导航元素中
var navEle = $("<nav></nav>").append(ul);
//把导航条添加到div 元素中
navEle.appendTo("#page_nav_area");
}
</script>
</body>
</html>
但是在点击“《”和“》”的时候还是会出现超出页码合理性的页数,所以就要在mybatis 全局配置文件中的pageHelper 插件中设置开启"页码合理参数"