对于Spring方面的知识重在多练习
目录
一、计算器
我们需要通过前后端的交互最终完成这样的界面以及完成需求
1、前端界面
因为主要学习的后端内容,所以前端的内容直接给大家
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="calc/sum" method="post">//action表示接下来要干啥,这里也就是操作后跳转到路径为calc/sum的页面
<h1>计算器</h1>
数字1:<input name="num1" type="text"><br>//这里表示输入的值赋值在num1
数字2:<input name="num2" type="text"><br>
<input type="submit" value=" 点击相加 ">
</form>
</body>
</html>
此时通过浏览器访问前端的界面就是这样的
url为文件名(calc.html)
2、约定前后端交互接口
接口又称API,是应用程序对外提供的服务的描述,用于交换信息和执行任务。
简单来说就是允许客户端给服务器发出什么样的请求并且每种请求预期收到什么样的http响应。
接口文档
项目开发前,前后端先约定交互接口,双方按照接口文档进行开发(接口文档就像双方的协议,双方共同履行协议的内容进行开发,接口文档一旦写好轻易不可以改变,如果要改变必须告知另一方)
需求分析:客户端提供进行加法的两个数字,服务器计算出结果后返回
定义接口
基于需求分析我们来定义接口
请求路径 | calc/sum |
请求方法 | GET |
接口描述 | 计算两个数的和 |
请求参数
类型 | 变量名 |
Integer | num1 |
Integer | num2 |
响应数据
Content-type | html |
这样我们的接口文档就完成了,接口文档的格式是自己定义的,目的是让客户端能看懂就好
3、服务器代码
首先按照我们在接口文档中定义的路径使用注释@RequestMapping来注释类和方法(不要忘了加@RestController)
@RestController
@RequestMapping("/calc")
public class CalcController {
@RequestMapping("/sum")
public String sum(Integer num1, Integer num2) {
Integer sum = num1 + num2;
return "<h1>相加后的和为: "+sum+"</h1>";
}
}
此时用浏览器测试得到的结果就可以直接是html标题
这里对后端方法进行单独测试是很有必要的,在前期学习Spring框架时最好“小步慢跑”,写完一个测试一个,到最后一起测试容易找不出错误
此时后端代码也测试完毕了,我们运行程序看结果
注意看两个url路径的变化
这样一个简单的加法计算器就完成了
二、用户登录
需求:用户输入账户和密码,后端进行校验密码是否正确
如果不正确,前端告知用户
如果正确,跳转到新页面显示用户名
后续再访问首页可以获取到用户信息
前端代码
有两个页面,第一个页面是登陆时的页面需输入账户和密码
依旧是在static的resource中创建html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h1>用户登录</h1>
用户名:<input name="userName" type="text" id="userName"><br>
密码:<input name="password" type="password" id="password"><br>
<input type="button" value="登录" onclick="login()">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
function login() {
}
</script>
</body>
</html>
测试结果
第二个页面是登陆成功后显示登陆人的名字的页面
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>用户登录首页</title>
</head>
<body>
登录人: <span id="loginUser"></span>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
</script>
</body>
</html>
测试结果
约定前后端交互接口
需求分析
对于后端人员不涉及前端的页面展示,只需要提供两个功能:(1)根据用户输入的账户和密码校验密码是否正确并告知前端 (2)在首页时如果有登录用户返回账户名,没有用户返回空
接口定义
登录页面:
请求路径 | /user/login |
请求方式 | POST |
接口描述 | 校验密码是否正确 |
请求参数
password | String |
username | String |
响应数据
Content-Type:html
响应内容:true(密码正确) false(密码错误)
首页:
需求分析
请求路径 | /user/getLoginUser |
请求方式 | GET |
接口描述 | 查询当前登录用户 |
服务器代码
登录页面
按照需求分析将框架建立好
package com.example.demo;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class LoginController {
@RequestMapping("/login")
public boolean login(String username, String password, HttpSession session) {
}
}
(1)当账户或密码为空时返回false(2)当账户密码不为空时判断对错,由于当前我们并没有学到操作数据库的操作所以暂时把代码写死,密码正确时将账户设置到服务器的session并返回true,
填写相应的逻辑后此时代码:
package com.example.demo;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class LoginController {
@RequestMapping("/login")
public boolean login(String userName, String password, HttpSession session) {
if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
return false;
}
if("xuhan".equals(userName)&&"0920".equals(password)) {
session.setAttribute("userName", userName); //在服务器session添加信息
//session.setAttribute("password", password);
return true;
}
return false;
}
}
服务器首页代码
这个页面我们需要在用户发出请求时查询它对应服务器的session是否为空,不为空就返回username,为空就返回空格;url地址也是我们在需求分析中规定的地址
package com.example.demo;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/getLoginUser")
public class getLoginUser {
@RequestMapping("/LoginUser")
public String getLoginUser(HttpSession session) {
String userName = (String) session.getAttribute("userName");
if(StringUtils.hasLength(userName)) {
return userName;
}
return " ";
}
}
此时我们后端两个界面的代码就写好了,接下来编写前端的代码,达到在前面界面输入账户密码能够跳转到后端页面的效果
在前端login代码的function中写入我们的逻辑,这里使用ajax来编写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h1>用户登录</h1>
用户名:<input name="userName" type="text" id="userName"><br>
密码:<input name="password" type="password" id="password"><br>
<input type="button" value="登录" onclick="login()">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
function login() {
$.ajax({
type : "post",
url : "user/login",
data : {
"userName" : $("#userName").val(),
"password" : $("#password").val()
},
success:function(result){ //result可以是任意名字,只表示从url地址的后端代码中返回的结果
if(result == true){ //当返回的结果为true代表密码正确,跳转到location的界面
location.href = "/index.html"
}else{
alert("密码错误"); //密码错误时提示密码错误
}
}
});
}
</script>
</body>
</html>
测试一下该页面,预期结果是:密码错误时提示密码错误,正确时跳转到首页
这里可以看出两种情况都测试完成没有错误,此时可以再对代码进行进一步完善,比如账户名为空或者账户名重复等情况。
接下来完善首页的前端代码也就是index.html
<script>
$.ajax({
type : "get",
url : "/getLoginUser/LoginUser",
success:function (result){
$("#loginUser").text(result);
}
})
</script>
,依旧使用ajax来实现,将从LoginUser获得的结果打印即可
此时测试一下首页
成功显示出了登陆人名字
三、留言板
需求:输入留言信息,点击提交后端把数据存储起来,页面展示输入的表白墙信息,例如这样的界面
前端页面只有一个,所以这次前端代码也只有一个文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>留言板</title>
<style>
.container {
width: 350px;
height: 300px;
margin: 0 auto;
/* border: 1px black solid; */
text-align: center;
}
.grey {
color: grey;
}
.container .row {
width: 350px;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
.container .row input {
width: 260px;
height: 30px;
}
#submit {
width: 350px;
height: 40px;
background-color: orange;
color: white;
border: none;
margin: 10px;
border-radius: 5px;
font-size: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>留言板</h1>
<p class="grey">输入后点击提交, 会将信息显示下方空白处</p>
<div class="row">
<span>谁:</span> <input type="text" name="" id="from">
</div>
<div class="row">
<span>对谁:</span> <input type="text" name="" id="to">
</div>
<div class="row">
<span>说什么:</span> <input type="text" name="" id="say">
</div>
<input type="button" value="提交" id="submit" onclick="submit()">
<!-- <div>A 对 B 说: hello</div> -->
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
function submit(){
//1. 获取留言的内容
var from = $('#from').val();
var to = $('#to').val();
var say = $('#say').val();
if (from== '' || to == '' || say == '') {
return;
}
//2. 构造节点
var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
//3. 把节点添加到页面上
$(".container").append(divE);
//4. 清空输入框的值
$('#from').val("");
$('#to').val("");
$('#say').val("");
}
</script>
</body>
</html>
这样一个示例的界面就展示好了,但需要前端调用后端的操作,所以后续还需在前端代码中添加逻辑
后端代码
需求分析:(1)用户输入留言信息之后后端把留言信息保存 (2)页面展示时需要从后端获取到所有的留言信息
接口定义:
获取全部信息可以用List来表示,用Json描述这个List数据
url | Message/getList |
响应 | Json格式 |
发表新留言也为Json格式
url | Message/publish |
响应 | Json格式 |
定义留言对象message类,需要包含from(发送人)to(接收人)msg(要说的话)
package com.example.demo;
import lombok.Data;
@Data //这里使用的lombok工具包
public class message {
private String from;
private String to;
private String msg;
}
MessageController类来包含获取留言和发送留言的方法
创建List表来存储msg信息
publish:先校验参数是否为空,为空返回false,不为空则向表中添加信息
getList:直接返回整个表的信息即可
package com.example.demo;
import org.apache.logging.log4j.message.Message;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/Message")
public class MessageController {
List<message> messages = new ArrayList<message>();
@RequestMapping("/publish")
public boolean publish(message mes) {
if(StringUtils.hasLength(mes.getFrom())
&&StringUtils.hasLength(mes.getTo())
&&StringUtils.hasLength(mes.getMsg())) {
messages.add(mes);
return true;
}
return false;
}
@RequestMapping("/getList")
public List<message> getMessages() {
return messages;
}
}
这样后端逻辑就写好了,接下来我们测试一下,用postman发送请求,预期的效果是当三个参数全都不为空时返回true,如果有一个为空则返回false
测试成功,符合预期
前端代码
在页面加载时就要获取全部的信息,添加load函数用于在页面加载的时候获得数据
load();
function load() {
$.ajax({
type: "get",
url: "/message/getList",
success: function (result) {
for (var message of result) {
var divE = "<div>" + message.from + "对" + message.to + "说:" +
message.message + "</div>";
$(".container").append(divE);
}
}
});
}
修改原来代码中的点击时间,在点击按钮时给服务器发送请求
function submit() {
//1. 获取留言的内容
var from = $('#from').val();
var to = $('#to').val();
var say = $('#say').val();
if (from == '' || to == '' || say == '') {
return;
}
$.ajax({
type: "post",
url: "/message/publish",
data: {
from: from,
to: to,
message: say
},
success: function (result) {
if (result) {
//2. 构造节点
var divE = "<div>" + from + "对" + to + "说:" + say + "</div>";
//3. 把节点添加到页面上
$(".container").append(divE);
//4. 清空输入框的值
$('#from').val("");
$('#to').val("");
$('#say').val("");
} else {
alert("发送失败");
}
}
});
}
这样前后端都写完了,我们进行测试结果成功
朋友们在萌新时期编写Spring代码时要学习注释的用法外,在编写时一定要注意前后端的变量名一致的地方要保持一致,否则很容易出现前端赋值变量后端无法收到的情况,我在用户登录这个项目排查了好久才发现原来是一个userName的n没大写 TAT
感谢观看
道阻且长,行则将至