说明:本代码只是为了本人练习前后端联动技术,包含html,jquery,thymeleaf模板、ajax请求及后端功能联动,方便自己查找及使用。
代码场景
场景1.table批量查询功能(有默认值),点击"查询最新数据"从后台查询覆盖默认显示的数据
默认table展示的数据
前端代吗
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<!--先加载css,再加载js,否则可能出错-->
<link th:href="@{bootstrap-3.4.1-dist/css/bootstrap.css}" rel="stylesheet" />
<link th:href="@{bootstrap-3.4.1-dist/css/bootstrap-theme.css}" rel="stylesheet" />
<!--切记:先加载jquery的js,再加载bootstrap.js-->
<script th:src="@{jquery/jquery3.6.0.js}"></script>
<script th:src="@{bootstrap-3.4.1-dist/js/bootstrap.js}"></script>
</head>
<body>
<div class="col-md-8">
<button type="submit" id="getTeacherList" class="btn btn-default">查询最新的数据</button>
<button type="button" id="addTeacher" class="btn btn-success">新建</button>
<button type="button" id="updateTeacher" class="btn btn-info">修改</button>
<button type="button" id="deleteTeacher" class="btn btn-warning">删除</button>
</div>
<!--表格-->
<div id="myTable" class="bs-example col-md-8" data-example-id="hoverable-table">
<table class="table table-hover" >
<thead>
<tr>
<th><input type="checkbox" value="" id="mycheckbox"></th>
<th>#</th>
<th>姓名</th>
<th>班级</th>
<th>所属学院</th>
<th>别名</th>
<th>性别</th>
</tr>
</thead>
<tbody id="myTbody1">
<tr>
<th><input type="checkbox" value=""></th>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
<td>Otto</td>
<td>男</td>
</tr>
<tr>
<th><input type="checkbox" value=""></th>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
<td>Thornton</td>
<td>女</td>
</tr>
<tr>
<th><input type="checkbox" value=""></th>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
<td>the Bird</td>
<td>女</td>
</tr>
</tbody>
</table>
</table>
</div>
</body>
<script type="text/javascript">
$("#getTeacherList").click(function () {
var params = {};
$.ajax({
type:"GET",
url:"/getTeacherList",
async: true,
dataType: "json",
data: params,
contentType: "application/json; charset=UTF-8",
success : function (response) {
if (response.code === 200) {
$("#myTbody1").html("");
var tr;
$.each(response.info, function (index, value) {
tr = tr + [
"<tr>",
"<th><input type='checkbox' value=''></th>",
"<th scope='row'>"+ value.id +"</th>",
"<td>"+ value.name +"</td>",
"<td>"+ value.classes +"</td>",
"<td>"+ value.college +"</td>",
"<td>"+ value.alias +"</td>",
];
if (value.sex === 0) {
tr = tr + "<td> 女 </td>";
} else {
tr = tr + "<td> 男</td>";
}
$("#myTbody1").append("</tr><tr>");
});
$("#myTbody1").append(tr);
}
}
});
});
</script>
</html>
后端代码
PracticeController
package com.example.demo.controller;
import com.example.demo.bean.Teacher;
import com.example.demo.response.Response;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@Controller
public class PracticeController {
private ConcurrentHashMap<String, List<Teacher>> cache = new ConcurrentHashMap<>();
@GetMapping(value = "")
public String index() {
return "index";
}
@PostConstruct
public void initCache() {
List<Teacher> teacherList = new ArrayList<>();
Teacher teacher1 = new Teacher();
teacher1.setId(1);
teacher1.setName("周杰伦");
teacher1.setClasses("三年二班");
teacher1.setCollege("魔法学院");
teacher1.setAlias("Jay Chou");
teacher1.setSex(1);
teacherList.add(teacher1);
Teacher teacher2 = new Teacher();
teacher2.setId(2);
teacher2.setName("丽萨");
teacher2.setClasses("三年二班");
teacher2.setCollege("魔法学院");
teacher2.setAlias("Lisa");
teacher2.setSex(0);
teacherList.add(teacher2);
cache.put("list", teacherList);
}
@GetMapping(value = "/getTeacherList")
@ResponseBody
public Response<List<Teacher>> getTeacherList(Model model) {
List<Teacher> teacherList = cache.get("list");
model.addAttribute("teacherList", teacherList);
model.addAttribute("flag", true);
teacherList.stream().forEach(System.out::println);
return Response.success(teacherList);
}
}
-----------------------------------------------------------------------------------------------
Teacher
package com.example.demo.bean;
import lombok.Data;
@Data
public class Teacher {
private Integer id;
private String name;
private String classes;
private String college;
private String alias;
private Integer sex;
}
点击后效果
场景2.新增,点击“新建”显示form表单,提交成功后隐藏form表单
点击“新建”弹窗form 说明:点击“新建”按钮,显示form表单且有默认值,提交成功后关闭form,内容为空提示错误提示
前端代吗
<div class="col-md-8">
<!--表单-->
<form id="myForm" style="display: none">
<div class="form-group" style="display: none">
<label for="name">id</label>
<input type="text" class="form-control" id="id" value="">
<span id="errorId" style="color: orangered"></span>
</div>
<div class="form-group">
<label for="name">姓名</label>
<input type="text" class="form-control" id="name" placeholder="please input name" value="测试姓名">
<span id="errorName" style="color: orangered"></span>
</div>
<div class="form-group">
<label for="classes">班级</label>
<input type="text" class="form-control" id="classes" placeholder="please input classes" value="测试班级">
<span id="errorClasses" style="color: orangered"></span>
</div>
<div class="form-group">
<label for="college">所属学院</label>
<input type="text" class="form-control" id="college" placeholder="please input college" value="测试所属学院">
<span id="errorCollege" style="color: orangered"></span>
</div>
<div class="form-group">
<label for="alias">别名</label>
<input type="text" class="form-control" id="alias" placeholder="please input alias" value="测试别名">
<span id="errorAlias" style="color: orangered"></span>
</div>
<div class="form-group">
<label >性别</label>
</div>
<div class="checkbox">
<label id="sex">
<input type="radio" name="sex" value=1>男
<input type="radio" name="sex" value=0 checked="checked">女
</label>
</div>
<span id="errorMyFormMessage" style="color: orangered"></span>
<button type="button" id="myFormSubmit" class="btn btn-success">提交</button>
<button type="button" id="myFormClose" class="btn btn-danger">关闭</button>
<!--y隐藏域,用于判断执行的是【1:增、2:改、3:删】-->
<input type="hidden" id="submitType" th:value=0>
</form>
</div>
----------------------------------------------------------------------------
var vertifyForm = function () {
var flag = true;
if ($("#name").val() == "") {
$("#errorName").html("name 不能为空");
flag = false;
}
if ($("#classes").val() == "") {
$("#errorClasses").html("classes 不能为空");
flag = false;
}
if ($("#college").val() == "") {
$("#errorCollege").html("college 不能为空");
flag = false;
}
if ($("#alias").val() == "") {
$("#errorAlias").html("alias 不能为空");
flag = false;
}
return flag;
}
----------------------------------------------------------------------------
$("#addTeacher").click(function () {
$("#name").val("测试姓名");
$("#classes").val("测试班级");
$("#college").val("测试所属学院");
$("#alias").val("测试别名");
$("#myForm").show();
$("#submitType").val(1);
});
----------------------------------------------------------------------------
$("#myFormSubmit").click(function () {
flag = vertifyForm();
if (!flag) return;
if ($("#submitType").val() == 1) {
var params = {
"name":$("#name").val(),
"classes":$("#classes").val(),
"college":$("#college").val(),
"alias":$("#alias").val(),
"sex":$("#sex :radio").val()
};
$.ajax({
type:"POST",
url:"/addTeacher",
async: true,
dataType: "json",
data: JSON.stringify(params),
contentType: "application/json; charset=UTF-8",
success : function (response) {
if (response.code === 200) {
var tr = [
"<tr>",
"<th><input type='checkbox' value=''></th>",
"<th scope='row'>" + response.info.id + "</th>",
"<td>"+ response.info.name +"</td>",
"<td>"+ response.info.classes +"</td>",
"<td>"+ response.info.college +"</td>",
"<td>"+ response.info.alias +"</td>",
];
if (response.info.sex === 0) {
tr = tr + "<td> 女 </td>";
} else {
tr = tr + "<td> 男</td>";
}
$("#myTbody1").append("</tr><tr>").append(tr);
$("#myForm").hide();
}
}
});
}
else if ($("#submitType").val() == 2) {
if ($("#myTbody1 :input:checked").length == 1) {
$("#errorMyFormMessage").html("")
var params = {
"id": $("#myTbody1 :input:checked").parent().parent().children().eq(1).html(),
"name":$("#name").val(),
"classes":$("#classes").val(),
"college":$("#college").val(),
"alias":$("#alias").val(),
"sex":$("#sex :radio:checked").val()
};
$.ajax({
type:"PUT",
url:"/updateTeacher",
async: true,
dataType: "json",
data: JSON.stringify(params),
contentType: "application/json; charset=UTF-8",
success : function (response) {
if (response.code === 200) {
$("#myTbody1 :input:checked").parent().parent().children().eq(2).html(response.info.name)
$("#myTbody1 :input:checked").parent().parent().children().eq(3).html(response.info.classes)
$("#myTbody1 :input:checked").parent().parent().children().eq(4).html(response.info.college)
$("#myTbody1 :input:checked").parent().parent().children().eq(5).html(response.info.alias)
if (response.info.sex == 0) {
$("#myTbody1 :input:checked").parent().parent().children().eq(6).html("女")
} else {
$("#myTbody1 :input:checked").parent().parent().children().eq(6).html("男")
}
$("#myForm").hide();
}
}
});
} else {
$("#errorMyFormMessage").html("只能选中一条记录提交!")
return;
}
}
});
后端代码
@PostMapping(value = "/addTeacher")
@ResponseBody
public Response<Teacher> addTeacher(@RequestBody Teacher teacher) {
List<Teacher> teacherList = cache.get("list");
Integer maxId = 0;
for (Teacher item : teacherList) {
if (item.getId() > maxId) maxId = item.getId();
}
teacher.setId(++maxId);
teacherList.add(teacher);
cache.put("list", teacherList);
cache.get("list").stream().forEach(System.out::println);
return Response.success(teacher);
}
提交成功后
场景3.更新,单选一条数据->弹窗->更新值->提交->更新页面
说明:更新和删除都是只能选中一条记录进行操作,否则警告弹窗 说明:先点击左侧勾选框-》如果选中一条记录则可再点击“更新”,并显示弹窗,如果选中多条会弹出警告
前端代吗
$("#mycheckbox").click(function () {
if ($(this).prop('checked')) {
$("#myTable input[type=checkbox]").prop("checked", true);
} else {
$("#myTable input[type=checkbox]").prop("checked", false);
}
});
----------------------------------------------------------------------------
$("#updateTeacher").click(function () {
if ($("#myTbody1 :input:checked").length != 1) {
alert("请选则其中一条数据");
return;
}
$("#name").val($("#myTbody1 :input:checked").parent().parent().children().eq(2).html());
$("#classes").val($("#myTbody1 :input:checked").parent().parent().children().eq(3).html());
$("#college").val($("#myTbody1 :input:checked").parent().parent().children().eq(4).html());
$("#alias").val($("#myTbody1 :input:checked").parent().parent().children().eq(5).html());
if ($("#myTbody1 :input:checked").parent().parent().children().eq(6).html() == "男") {
$("#sex").children().eq(0).prop("checked", true);
} else {
$("#sex").children().eq(1).prop("checked", true);
}
$("#myForm").show();
$("#submitType").val(2);
});
后端代码
@PutMapping(value = "/updateTeacher")
@ResponseBody
public Response<Teacher> updateTeacher(@RequestBody Teacher teacher) {
List<Teacher> teacherList = cache.get("list");
Teacher teacherNew = new Teacher();
for (Teacher item : teacherList) {
if (item.getId() == teacher.getId()) {
teacherNew.setId(teacher.getId());
teacherNew.setName(teacher.getName());
teacherNew.setClasses(teacher.getClasses());
teacherNew.setCollege(teacher.getCollege());
teacherNew.setAlias(teacher.getAlias());
teacherNew.setSex(teacher.getSex());
teacherList.remove(item);
teacherList.add(teacherNew);
}
}
cache.put("list", teacherList);
cache.get("list").stream().forEach(System.out::println);
return Response.success(teacherNew);
}
场景4.删除功能
说明:更新和删除都是只能选中一条记录进行操作,否则警告弹窗
前端代码
$("#deleteTeacher").click(function () {
console.log("***************");
console.log($("#myTbody1 :input:checked").length)
$("#submitType").val(3);
if ($("#myTbody1 :input:checked").length == 1) {
$("#errorMyFormMessage").html("")
var params = {
};
$.ajax({
type:"DELETE",
url:"/deleteTeacher?id=" + $("#myTbody1 :input:checked").parent().parent().children().eq(1).html(),
async: true,
dataType: "json",
data: params,
contentType: "application/json; charset=UTF-8",
success : function (response) {
if (response.code === 200) {
$("#myTbody1 :input:checked").closest('tr').remove();
$("#myForm").hide();
}
}
});
} else {
alert("请选则其中一条数据");
return;
}
});
后端代码
@DeleteMapping(value = "/deleteTeacher")
@ResponseBody
public Response<Teacher> deleteTeacher(@RequestParam Integer id) {
List<Teacher> teacherList = cache.get("list");
Iterator<Teacher> iterator = teacherList.iterator();
while(iterator.hasNext()){
Teacher item = iterator.next();
if (item.getId() == id) {
iterator.remove();
}
}
cache.put("list", teacherList);
cache.get("list").stream().forEach(System.out::println);
return Response.success();
}
报错场景说明
1.jquery调用post请求,后台一直报400,显示:JSON Parse error: Unrecognized token
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'name': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'name': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')<EOL> at [Source: (PushbackInputStream); line: 1, column: 6]]
错误代码:
$("#addTeacher").click(function () {
flag = vertifyForm();
var params = {
"name":$("#name").val(),
"classes":$("#classes").val(),
"college":$("#college").val(),
"alias":$("#alias").val(),
"sex":$("#sex :checkbox").val()
};
$.ajax({
type:"POST",
url:"/addTeacher",
async: true,
dataType: "json",
data: params,
contentType: "application/json; charset=UTF-8",
success : function (response) {
if (response.code === 200) {
console.log("***************");
console.log(response);
}
}
});
});
解决办法:ajax提交post请求时,使用JSON.stringify(data) 序列化请求参数(data为请求接口的数据) 正确代码:data: JSON.stringify(params),
2.清空form表单问题,例如input和checkbox标签
之前碰到的问题:标签checkbox一直无法清除
var emptyForm = function () {
$("#name").val("");
$("#classes").val("");
$("#college").val("");
$("#alias").val("");
$("#sex :checkbox").removeAttr("checked");
}
3.引入Bootstrap和Jquery显示404找不到文件
说明:引入css和第三方js顺序,先加载css,再加载jquery的js,最后加载bootstrap.js,否则加载顺序不对可能出错
发生错误原因:我写的绝对路径和相对路径都不对,另外我也不确信相对路径 究竟是从哪里开始算,所以一直报404
正确的图片路径及代吗如下
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<!--先加载css,再加载js,否则可能出错-->
<link th:href="@{bootstrap-3.4.1-dist/css/bootstrap.css}" rel="stylesheet" />
<link th:href="@{bootstrap-3.4.1-dist/css/bootstrap-theme.css}" rel="stylesheet" />
<!--切记:先加载jquery的js,再加载bootstrap.js-->
<script th:src="@{jquery/jquery3.6.0.js}"></script>
<script th:src="@{bootstrap-3.4.1-dist/js/bootstrap.js}"></script>
</head>
4.radio对应的性别想实现,点击男,则女取消勾选,实际情况是取消勾选不了,且男女都会选中,具体如图
前端代吗如下
<div class="checkbox">
<label id="sex">
<input type="radio" value=1>男
<input type="radio" value=0 checked="checked">女
</label>
</div>
问题产生原因: 没设置name属性造成 解决办法:两个input份别补充name属性即可默认实现每次只能选中一个,另外往后初始化标签栏,属性id和name最好默认都给上,防止莫名出错
<label id="sex">
<input type="radio" name="sex" value=1>男
<input type="radio" name="sex" value=0 checked="checked">女
</label>
5.删除功能报错 java.util.ConcurrentModificationException: null
出错场景描述: 后台模拟一个本地缓存ConcurrentHashMap来存放list信息,页面点击删除按钮时后台删除list里面的某个记录,举例代码如下,该问题报错点在于,当既遍历list,同时又想操作删除某个元素时,就会产生这个报错
private ConcurrentHashMap<String, List<Teacher>> cache = new ConcurrentHashMap<>();
@PostConstruct
public void initCache() {
List<Teacher> teacherList = new ArrayList<>();
Teacher teacher1 = new Teacher();
teacher1.setId(1);
teacher1.setName("周杰伦");
teacher1.setClasses("三年二班");
teacher1.setCollege("魔法学院");
teacher1.setAlias("Jay Chou");
teacher1.setSex(1);
teacherList.add(teacher1);
Teacher teacher2 = new Teacher();
teacher2.setId(2);
teacher2.setName("丽萨");
teacher2.setClasses("三年二班");
teacher2.setCollege("魔法学院");
teacher2.setAlias("Lisa");
teacher2.setSex(0);
teacherList.add(teacher2);
cache.put("list", teacherList);
}
@DeleteMapping(value = "/deleteTeacher")
@ResponseBody
public Response<Teacher> deleteTeacher(@RequestParam Integer id) {
List<Teacher> teacherList = cache.get("list");
for (Teacher item : teacherList) {
if (item.getId() == id) {
teacherList.remove(item);
}
}
cache.put("list", teacherList);
cache.get("list").stream().forEach(System.out::println);
return Response.success();
}
解决办法,不使用teacherList.remove(item);方法,而使用迭代器的iterator.remove();
@DeleteMapping(value = "/deleteTeacher")
@ResponseBody
public Response<Teacher> deleteTeacher(@RequestParam Integer id) {
List<Teacher> teacherList = cache.get("list");
Iterator<Teacher> iterator = teacherList.iterator();
while(iterator.hasNext()){
Teacher item = iterator.next();
if (item.getId() == id) {
iterator.remove();
}
}
cache.put("list", teacherList);
cache.get("list").stream().forEach(System.out::println);
return Response.success();
}
|