說明:本程式碼只是為了本人練習前後端聯動技術,包含html,jquery,thymeleaf模板、ajax請求及後端功能聯動,方便自己查詢及使用。
@
- 程式碼場景
- 場景1.table批次查詢功能(有預設值),點選"查詢最新資料"從後臺查詢覆蓋預設顯示的資料
- 場景2.新增,點選“新建”顯示form表單,提交成功後隱藏form表單
- 場景3.更新,單選一條資料->彈窗->更新值->提交->更新頁面
- 場景4.刪除功能
- 報錯場景說明
- 1.jquery呼叫post請求,後臺一直報400,顯示:JSON Parse error: Unrecognized token
- 2.清空form表單問題,例如input和checkbox標籤
- 3.引入Bootstrap和Jquery顯示404找不到檔案
- 4.radio對應的性別想實現,點選男,則女取消勾選,實際情況是取消勾選不了,且男女都會選中,具體如圖
- 5.刪除功能報錯 java.util.ConcurrentModificationException: null
- 6.更新功能報錯 java.util.ConcurrentModificationException: null
- 本人相關其他文章連結
程式碼場景
場景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) {
//清空table內容
$("#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;
/**
* @Author 211145187
* @Date 2022/2/25 13:54
**/
@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;
/**
* @Author 211145187
* @Date 2022/2/23 09:32
**/
@Data
public class Teacher {
//id
private Integer id;
//姓名
private String name;
//班級
private String classes;
//所屬學院
private String college;
//別名
private String alias;
//性別【0:女 1:男】
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>
----------------------------------------------------------------------------
//點選“關閉按鈕”關閉視窗
$("#myFormClose").click(function () {
$("#myForm").hide();
});
----------------------------------------------------------------------------
//校驗form
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",
//注意:ajax提交post請求時,必須使用JSON.stringify(data) 序列化請求引數,否則報400
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) {
//$("#myTbody1 :input:checked").length 用於獲取checkbox的選中條數
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",
//注意:ajax提交post請求時,必須使用JSON.stringify(data) 序列化請求引數,否則報400
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();
}
//模擬id自增
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");
List<Teacher> newTeacherList = new ArrayList<>();
Teacher teacherNew = null;
Iterator<Teacher> iterator = teacherList.iterator();
while(iterator.hasNext()){
Teacher item = iterator.next();
if (item.getId() == teacher.getId()) {
teacherNew = new Teacher();
teacherNew.setId(teacher.getId());
teacherNew.setName(teacher.getName());
teacherNew.setClasses(teacher.getClasses());
teacherNew.setCollege(teacher.getCollege());
teacherNew.setAlias(teacher.getAlias());
teacherNew.setSex(teacher.getSex());
iterator.remove();
newTeacherList.add(teacherNew);
continue; //跳過此次迴圈進入下一次迴圈中
}
newTeacherList.add(item);
}
cache.put("list", newTeacherList);
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);
//$("#myTbody1 :input:checked").length 用於獲取checkbox的選中條數
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",
//注意:ajax提交post請求時,必須使用JSON.stringify(data) 序列化請求引數,否則報400
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 () {
// $("#myForm").show()0987;
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",
//ajax提交post請求時,必須使用JSON.stringify(data) 序列化請求引數,否則報400
data: params,
// data: JSON.stringify(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一直無法清除
//清空form - 這裡是正確的代嗎
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>
會議詳情
重要資訊
- 大會官網:https://ais.cn/u/vEbMBz
大會介紹
第四屆公共管理與大資料分析國際學術會議 (PMBDA 2024)將於2024年12月20-22日在中國青島召開。會議主題主要圍繞公共管理與大資料分析等相關研究領域展開討論,旨在為相關研究方向的專家學者及企業發展人提供一個分享研究成果、討論存在的問題與挑戰、探索前沿科技的國際性合作交流平臺。現誠邀國內外高校、科研機構專家、學者,企業界人士及其他相關人員踴躍投稿並參會交流。
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();
}
6.更新功能報錯 java.util.ConcurrentModificationException: null
更新和刪除功能型別,想遍歷list進行刪除或者新增操作,
思路:便利list碰到匹配的就刪除,用form傳過來的新值新增進list中,從而達到更新目的,
問題出在:如果操作同一個list,哪怕用迭代器也會報錯,正確思路是,從新建立個list,便利碰到不同的直接新增,碰到匹配的就儲存到新的實體物件中,再新增到list中
本人相關其他文章連結
1.JQuery選擇器+DOM操作+事件+DOM與JQuery物件間的轉化
2.個人練習前端技術使用Bootstrap、JQuery、thymeleaf
3.JavaScript入門及基礎知識介紹
4.AJax(XHR+Get和Post+AJax的封裝)
5.SpringBoot專案的html頁面使用axios進行get post請求