文章目录
一、重点思想
重点思想看过来哇!!!
- 我个人认为做前后端分离的项目,无非就是前后端数据的相互传递,那么以这个思想为基础,学习收参和传参的方式就显得格外重要;
- 另外,我们是以JSON字符串的形式传递数据的,还需要学习JSON字符串的转换与解析!
1、从前端向后端传递数据:
1.将前端数据封装成一个对象:
2.将对象转化为JSON字符串:
3.后端获取对象或属性:
4.解析为Java对象:
2、从后端向前端传递数据
- 将Java对象转化为JSON字符串:
String s = JSON.toJSONString(student); - 实例化一个PrintWrite对象,调用write方法向前端传递:
PrintWriter writer = res.getWriter(); - 前端接收到后端的数据:
let data = xmlHttpRequest.responseText; - 将JSON字符串解析为JS对象:
et parse = JSON.parse(data);(拿到的是一个数组或者一个对象)
二、使用Ajax发起请求的方式
这一部分可看可不看,我主要是自己梳理一下代码
1、使用GET方式向前端请求数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function ajax1(){
//以下是AJAX请求流程
let xmlHttpRequest = new XMLHttpRequest();//1.创建XMLHttpRequest对象
xmlHttpRequest.open("get","/javawebstudy2025_war_exploded/ajax1",true)//2.初始化请求,添加请求参数
xmlHttpRequest.onreadystatechange=function(){//3.设置状态监听回调
if (xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
let data = xmlHttpRequest.responseText;
console.log(data);
document.querySelector("#res").innerHTML=data;
}
}
xmlHttpRequest.send();//4.发送请求
}
</script>
</head>
<body>
<h1>Ajax测试开始啦!</h1>
<div id="res" style="width: 300px;height: 200px;background: aliceblue;border:2px solid lightblue">
仅更换内容,不刷新页面
</div>
<button onclick="ajax1()">更换</button>
<h2>版权信息</h2>
</body>
</html>
小羊碎碎念:
- xmlHttpRequest.open(“get”,“/javawebstudy2025_war_exploded/ajax1”,true),该方法的三个参数分别是:请求方法类型,url,异步请求。(异步请求不写默认为true)
- 异步请求:
@WebServlet("/ajax1")
public class TestAjax1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.write("我是来自后端的数据!");//后端向前端传递的数据
}
}
小羊碎碎念:
- WebServlet 注解:用于注册 Servlet ,将 Servlet 类与 Web 容器(如 Tomcat)建立关联,让容器能够识别、加载并正确调用 Servlet 处理 HTTP 请求。
- 创建 Servlet 类的常见方式:
继承HttpServlet类(重写doGet、doPost方法或者直接实现service方法也可以);
继承GenerricServlet类(重写service方法);
实现Servlet接口(实现所有抽象方法)。- 实现一个接口必须实现他的抽象方法,否则定义该类为抽象类。
2、使用Get请求从前端向后端传递数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function ajax2(){
let xmlHttpRequest = new XMLHttpRequest();
//获取DOM对象,再获取它的值
let user = document.querySelector(".user").value;
let pwd = document.querySelector(".pwd").value;
xmlHttpRequest.open('get','/javawebstudy2025_war_exploded/ajax2?name='+user+'&password='+pwd);
// 异步请求不写默认是true
xmlHttpRequest.onreadystatechange=function(){
if (xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
let data = xmlHttpRequest.responseText;
document.querySelector(".res").innerHTML=data;
}
}
xmlHttpRequest.send();
}
</script>
</head>
<body>
<div class="res" style="width: 200px;height: 100px; border:lightskyblue 2px solid">
用户名和密码是什么?
</div>
用户名:<input type="text" class="user"><br>
密码:<input type="text" class="pwd"><br>
<button onclick="ajax2()">提交</button>
</body>
</html>
@WebServlet("/ajax2")
public class TestAjax2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
String name = req.getParameter("name");
String password = req.getParameter("password");
writer.write("用户名是"+name+",密码是"+password+"!");
}
}
三、主要思想代码示例
首先,要明确是从前端向后端传数据还是从后端向前端传数据。
第二,数据在前后端之间以JSON字符串的形式进行传递。那就涉及到JSON字符串的转换与解析
1、获取DOM对象、定义全局变量、初始化
let tabObj = document.getElementById("tab")
let sname = document.getElementById("sname");
let ssex = document.getElementById("ssex");
let sage = document.getElementById("sage");
let user = document.getElementById("user");
let pwd = document.getElementById("pwd");
let jsonData;
let indexc;
let id;
window.onload = function () {
ajaxGetData();
}
function ajaxGetData() {
let xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("get", "/javawebstudy2025_war_exploded/Do?method=selectDo", true);
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
let data = xmlHttpRequest.responseText;
jsonData = JSON.parse(data);
let maxIndex = jsonData[jsonData.length - 1].id + 1;
initData("tab");
}
}
xmlHttpRequest.send();
}
2、从前端向后端传数据
(1)校验管理员
/**
* 6、校验管理员、
* 关于传参选择普通键值对还是JSON字符串:
* 简单数据用普通键值对,直观简洁,在 URL拼接或传统表单提交时很方便,后端解析也容易。
* 而像实体类这种包含多个属性、结构较复杂的数据,JSON 字符串能更好呈现其完整结构,方便前后端处理和交互
* 这里测试过了,两种方法都是可以的
*/
function isAdmin() {
let xmlHttpRequest = new XMLHttpRequest();
let newData={
"admin":user.value,
"password":pwd.value
}
let s = encodeURIComponent(JSON.stringify(newData));
xmlHttpRequest.open("get", "/javawebstudy2025_war_exploded/Do?method=isAdminDo&Data="+s, true);
/*let admin=user.value
let password=pwd.value
xmlHttpRequest.open("get", "/javawebstudy2025_war_exploded/Do?method=isAdminDo&admin="+admin+"&password="+password, true);*/
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
let data = xmlHttpRequest.responseText;
let parse = JSON.parse(data);
if(parse.msg=="success"){
//前端中==就可以比较两个字符串,而Java中需要用equals比较两个对象是否相等,==比较两个对象是否是同一个对象
window.location.href="showList copy 2.html"
}else{
alert("用户名或密码错误,请重试")
}
}
}
xmlHttpRequest.send();
}
/**
* 逻辑2:登录
*
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
public void isAdminDo(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
String data = servletRequest.getParameter("Data");
JSONObject jsonObject = JSONObject.parseObject(data);
String admin = jsonObject.getString("admin");
String password = jsonObject.getString("password");
/* String admin = servletRequest.getParameter("admin");
String password = servletRequest.getParameter("password");*/
StudentImplService studentImplService = new StudentImplService();
Boolean login = studentImplService.isAdminService(admin, password);
// System.out.println("login = " + login);
PrintWriter writer = servletResponse.getWriter();
if(login!=null){
// HttpServletResponse servletResponse1 = (HttpServletResponse) servletResponse;
// servletResponse1.sendRedirect("showList copy 2.html");
// Result result = new Result(1,"success",null);
writer.write(JSON.toJSONString(Result.success()));
}else{
//return Result.error("登陆失败");
writer.write(JSON.toJSONString(Result.error("登录失败")));
// writer.write(333);
}
}
(2)添加
/**
* 2、添加数据
* @returns
*/
function addData() {
var maxIndex = jsonData[jsonData.length - 1].id + 1
if (sname.value == "" || ssex.value == "" || sage.value == "") {
alert("数据不完整")
return false;
}
let newData = {
"id": maxIndex,
"sname": sname.value,
"ssex": ssex.value,
"sage": sage.value,
}
let jsonStr = encodeURIComponent(JSON.stringify(newData));
// let jsonStr = JSON.stringify(newData);
// alert(jsonStr)
let xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("get", "/javawebstudy2025_war_exploded/Do?method=addDo&jsondata=" + jsonStr, true);
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
let data = xmlHttpRequest.responseText;
ajaxGetData();
}
}
xmlHttpRequest.send();
}
/**
* 逻辑4:添加
*
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
public void addDo(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest req1 = (HttpServletRequest) servletRequest;
HttpSession session = req1.getSession(false);
PrintWriter writer = servletResponse.getWriter();
String newStu = servletRequest.getParameter("jsondata");
JSONObject jsonObject = JSONObject.parseObject(newStu);
/*这里收参方式有问题,在前面已经通过getParameter获取到了jsondata,后面在取键时应该.属性名
String sname = servletRequest.getParameter("sname");
String ssex = servletRequest.getParameter("ssex");
String sage = servletRequest.getParameter("sage");*/
String sname = jsonObject.getString("sname");
String ssex = jsonObject.getString("ssex");
String sage = jsonObject.getString("sage");
Student student = new Student(null, sname, ssex, sage);
int add = studentImplService.insertService(student);
if (add > 0) {
// servletRequest.getRequestDispatcher("Do?method=selectDo").forward(servletRequest, servletResponse);
HttpServletResponse servletResponse1 = (HttpServletResponse) servletResponse;
// servletResponse1.sendRedirect("Do?method=selectDo");
} else {
System.out.println("添加失败!");
}
}
(3)实现更新
* 5、更新数据:将表格里的新数据又赋给json对象各属性的值
* 这个不用闭包
*/
function updateData1() {
let xmlHttpRequest = new XMLHttpRequest();
let newData = {
"id": id,//这里我就使用的是全局变量,以后每次先点击更新按钮,id就会被重新赋值为当前学号
"sname": sname.value,
"ssex": ssex.value,
"sage": sage.value,
}
let s = encodeURIComponent(JSON.stringify(newData));
xmlHttpRequest.open("get", "/javawebstudy2025_war_exploded/Do?method=updateDo&newStu=" + s, true);
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
ajaxGetData();
}
}
xmlHttpRequest.send();
}
/**
* 逻辑6:真正实现更新
* @param req
* @param res
* @throws ServletException
* @throws IOException
*/
public void updateDo(ServletRequest req, ServletResponse res) throws ServletException, IOException {
String newStu = req.getParameter("newStu");
JSONObject jsonObject = JSONObject.parseObject(newStu);
Integer id = jsonObject.getInteger("id");
String sname = jsonObject.getString("sname");
String ssex = jsonObject.getString("ssex");
String sage = jsonObject.getString("sage");
Student student = new Student(id, sname, ssex, sage);
int update = studentImplService.updateService(student);
if (update < 0) {
System.out.println("更新失败!");
}
}
}
3、从后端向前端传数据
(1)查询数据
/**
* 1、渲染json数据,并且动态生成表格
*/
function initData(tab) {
// 清理原来的DOM结构(不清理表头)
tabObj.innerHTML = "";
for (let index = 0; index < jsonData.length; index++) {
var trObj = document.createElement("tr")
if (index % 2 == 0) {
trObj.style.backgroundColor = "lightblue"//偶数行是蓝色
}
for (let pos = 0; pos < Object.keys(jsonData[0]).length + 2; pos++) {
var tdObj = document.createElement("td")
trObj.appendChild(tdObj)
}
let tdObjChildren = trObj.children;
let m = 0;
Object.keys(jsonData[index]).forEach(key => {
tdObjChildren[m++].innerHTML = jsonData[index][key];
}
)
let btnObj = document.createElement("button")
btnObj.innerHTML = "删除";
btnObj.onclick = delDate(index);
// tdObjChildren[4].appendChild(btnObj)
tdObjChildren[Object.keys(jsonData[0]).length].appendChild(btnObj)
let btnObj1 = document.createElement("button")
btnObj1.innerHTML = "更新";
btnObj1.onclick = updateData(jsonData[index].id)
tdObjChildren[Object.keys(jsonData[0]).length + 1].appendChild(btnObj1)
tabObj.appendChild(trObj)
}
}
/**
* 逻辑1:渲染数据
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
public void selectDo(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
HttpServletRequest req1 = (HttpServletRequest) req;
HttpSession session = req1.getSession(false);
HttpServletResponse resp1 = (HttpServletResponse) resp;
List<Student> allData = studentImplService.getAllService();
String s = JSON.toJSONString(allData);
PrintWriter writer = resp.getWriter();
writer.write(s);
// req1.setAttribute("data", allData);
// req1.getRequestDispatcher("ShowList1.jsp").forward(req1, resp1);
}
(2)获取一条数据
/**
* 4、更新数据:将json数据放在表格里
*/
function updateData(index) {
let index1 = index//闭包函数写法
return function () {
indexc = index1;//全局的indexc记录了要修改的数据的下标
let xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("get", "/javawebstudy2025_war_exploded/Do?method=getOneDo&id=" + indexc, true);
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
let data = xmlHttpRequest.responseText;
/* if(data.code==200 && data.msg=="success")
{
}*/
let parse = JSON.parse(data);
id = parse.id;//我将这里的id设置为全局变量,为了在真正实现更新时给“id”值
// console.log(id);
sname.value = parse.name//注意,这里返回了一条从数据库里面查出来的数据,你通过.属性名时这里的属性名是表中字段名
ssex.value = parse.sex
sage.value = parse.age
// console.log(parse);
ajaxGetData();
}
}
xmlHttpRequest.send();
}
}
/**
* 逻辑5:获取一条数据:服务器端渲染
* @param req
* @param res
* @throws ServletException
* @throws IOException
*/
public void getOneDo(ServletRequest req, ServletResponse res) throws ServletException, IOException {
Integer id = Integer.valueOf(req.getParameter("id"));
Student student = studentImplService.getOneService(id);
String s = JSON.toJSONString(student);
PrintWriter writer = res.getWriter();
writer.write(s);
}
(3)删除一条数据
/**
* 3、删除数据
* @param {*} index
* @returns
*/
//也可以在调用处传参jsonData[index].id,然后让他等于index1,在地址里面传参index1即可
function delDate(index) {
let index1 = index;
return function () {
if (confirm("确认删除吗?")) {
let xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("get", "/javawebstudy2025_war_exploded/Do?method=delDo&id=" + jsonData[index1].id, true);
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
// let data = xmlHttpRequest.responseText;
ajaxGetData();
}
}
xmlHttpRequest.send();
}
}
}
/**
* 逻辑3;删除
*
* @param req
* @param res
* @throws ServletException
* @throws IOException
*/
public void delDo(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// 获取删除的那条记录的主键ID
String id = req.getParameter("id");
System.out.println("id = " + id);
// 数据访问层
Integer idd = Integer.valueOf(id);
int i = studentImplService.delService(idd);
System.out.println("i = " + i);
if (i > 0) {
// req.getRequestDispatcher("/Do?method=selectDo").forward(req, res);
HttpServletResponse servletResponse1 = (HttpServletResponse) res;
// servletResponse1.sendRedirect("Do?method=selectDo");
} else {
System.out.println("删除失败!");
}
}
4、数据访问层展示
我的这个项目实现了数据的增删查改与校验管理员(通过vscode中我那个纯前端的项目改造的),分别写了两个实体类:学生类和管理员类,我也为他们分别写了数据访层。我记得当时没有写管理员类,然后通过mybatis操作数据库失败了,所以定义管理员类是必要的。
package dao;
import moudle.Student;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface StudentDao {
// 渲染数据
@Select("select * from Student")
List<Student> getAllDao();
// 删除
@Delete("delete from student where id=#{id}")
int delDao(Integer id);
// 添加
@Insert("insert into student values (null,#{name},#{sex},#{age})")
int insertDao(Student student);
// 拿到一条数据
@Select("select * from student where id=#{id}")
Student getOneDao(Integer id);
// 更新
@Update("update student set name=#{name},sex=#{sex},age=#{age} where id=#{id}")
int updateDao(Student student);
// 分页查询
@Select("select * from student limit #{start},#{pageSize}")
List<Student> fenYeDao(@Param("start") Integer start,@Param("pageSize") Integer pageSize);
}
package dao;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface ManagerDao {
@Select("select * from manager where admin=#{admin} and password=#{password}")
Boolean isAdminDao(@Param("admin") String admin,@Param("password") String password);
}
5、分页查询前端代码备份
这是一个jsp文件
<%@ page import="moudle.Student" %>
<%@ page import="java.util.List" %>
<%@ page import="service.impl.StudentImplService" %>
<%--
Created by IntelliJ IDEA.
User: 34806
Date: 2025/5/7
Time: 10:15
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生信息列表展示</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.staticfile.net/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.net/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.net/popper.js/1.15.0/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.net/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<%
// List<Student> data = (List<Student>) request.getAttribute("data");
/**
* 作用域问题:在 JSP 中,
* request.getAttribute("data") 获取数据,
* request 作用域仅在一次请求 - 响应过程中有效。
* 点击下一页是新请求,之前 request 作用域里的数据不会自动带到新请求中。
* 若没有重新设置 data 到新 request 作用域,就获取不到。
*/
StudentImplService studentImplService1 = new StudentImplService();
List<Student> data = studentImplService1.getAllService();
// 1.计算有多少条数据
int totalCount = data.size();
// 2.设置每一页有几条数据
int pageSize = 3;
// 3.计算有多少页
int pageCount = (int) (Math.ceil(totalCount * 1.0 / pageSize));
// 4.获取当前页
int curPage = request.getParameter("curPage") == null ?
1 : Integer.valueOf(request.getParameter("curPage"));
// 计算偏移值
int offSet = (curPage - 1) * 3;
// 5.获取当前页的数据
StudentImplService studentImplService = new StudentImplService();
List<Student> students = studentImplService.fenYeService(offSet, pageSize);
%>
<%--你依然保持在线!--%>
<a href='/javawebstudy2025_war_exploded/logout'>退出</a>
<table class="table">
<thead class="thead-dark">
<tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>操作1</th>
<th>操作2</th>
</tr>
</thead>
<tbody>
<%
for (int i = 0; i < students.size(); i++) {
%>
<tr>
<td>
<%=students.get(i).getId()%>
</td>
<td>
<%=students.get(i).getName()%>
</td>
<td>
<%=students.get(i).getSex()%>
</td>
<td>
<%=students.get(i).getAge()%>
</td>
<td>
<a href="/javawebstudy2025_war_exploded/Do?method=delDo&id=<%=students.get(i).getId()%>"
onclick="if(confirm('确认删除吗?')) return true;return false;">删除</a>
</td>
<td>
<a href="/javawebstudy2025_war_exploded/Do?method=getOneDo&id=<%=students.get(i).getId()%>">更新</a>
</td>
</tr>
<%
}
%>
<%
if (curPage == 1) {
%>
<tr>
<td>首页</td>
<td>上一页</td>
<td><a href="ShowList1.jsp?curPage=<%=curPage+1%>">下一页</a></td>
<td><a href="ShowList1.jsp?curPage=<%=pageCount%>">尾页</a></td>
</tr>
<%
} else if (curPage == pageCount) {
%>
<tr>
<td><a href="ShowList1.jsp?curPage=1">首页</a></td>
<td><a href="ShowList1.jsp?curPage=<%=curPage-1%>">上一页</a></td>
<td>下一页</td>
<td>尾页</td>
</tr>
<%
} else {
%>
<tr>
<td><a href="ShowList1.jsp?curPage=1">首页</a></td>
<td><a href="ShowList1.jsp?curPage=<%=curPage-1%>">上一页</a></td>
<td><a href="ShowList1.jsp?curPage=<%=curPage+1%>">下一页</a></td>
<td><a href="ShowList1.jsp?curPage=<%=pageCount%>">尾页</a></td>
</tr>
<%
}
%>
</tbody>
</table>
<button style='padding: 10px 20px;display: block; margin: 0 auto;'>
<a href="/javawebstudy2025_war_exploded/add.html">添加</a>
</button>
</body>
</html>