云计算百科
云计算领域专业知识百科平台

Spring MVC小案例(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">
<h1>计算器</h1>
数字1:<input name="num1" type="text"><br>
数字2:<input name="num2" type="text"><br>
<input type="submit" value=" 点击相加 ">
</form>
</body>

</html>

@RestController
public class CalcController {
@RequestMapping("/calc/sum")
public String sum(@RequestParam Integer num1, @RequestParam Integer num2){
int sum=num1+num2;
return "相加的结果为:"+sum;
}
}

代码解释以及注意事项:前端代码中的name=num1以及name=num2就跟后端代码中的num1和num2相对应,也就是说后端是去收到前端传来的名为num1和num2的参数进行相加返回结果的,如果你后端不想叫这个名字的话也可以通过@RequestParam注解来进行后端代码中的参数的改名,我这里没有写,我这个是用到了这个注解另一个特性,就是参数不能为空,然后前端代码的开头是将用户输入的获取到并且传给calc/sum这个方法,然后就是完成了前后端的一个交互了

那可能会有一个疑问说为什么会跳转到另一个网页,这个是那个机制或者代码实现的呢:关键就在前端代码body中开头的一行,这是HTML表单的默认提交行为,具体的行为如下:

当你点击「点击相加」按钮时,浏览器默认会做三件事:

  • 收集表单中的 num1、num2 两个参数。

  • 向 action 指定的 /calc/sum 接口发送 POST 请求。

  • 用服务器返回的响应替换当前标签页显示的内容。

  • 所以,你看到的效果就是:原来的计算器页面不见了,浏览器地址变成接口地址,页面显示计算结果。

    二,用户登录

    我们要实现一个页面,当用户输入用户和密码错误的时候,会有个错误的弹窗提示,当正确的时候,我们会跳转到一个显示着登陆人:(正确的登录名字)这样的页面

    那我们首先需要第一步就是创建一个登录的接口,根据传入的名字以及密码来判断是正确还是错误来进行返回,这里我们需要注意的是由于我们需要返回的页面要显示名字,但是我们http是无记忆的,所以我们需要用到session来保存正确的用户名

    后端登录接口和获取session代码

    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 Userlogin {
    @RequestMapping("/login")
    public Boolean login(String userName, String password, HttpSession session){
    //先验证数据是否有效
    if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
    return false;
    }
    //判断数据是否匹配,因为我们还没有学习到数据库跟这个结合的内容,所以我们先使用固定的用户名以及密码
    if ("admin".equals(userName)&&"admin".equals(password)){
    //因为http没有记忆,所以得用上session
    session.setAttribute("userName",userName);
    return true;
    }
    return false;
    }
    @RequestMapping("/getUsername")
    public String getUsername(HttpSession session){
    String userName =(String) session.getAttribute("userName");
    return userName==null?"账号或密码错误":userName;
    }

    }

    接下来是对于接口的测试

    第二步就是开始编辑我们的页面,在这里我们使用ajax的方式来编写,在写之前,我们需要引入一个jQuery,这样可以让我们的代码写起来更加的方便,我们通过下面这个链接进去右键下载到桌面,然后将jQuery引入进来

    https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js

    ajax

    ajax的介绍:

    简单来说,AJAX 是一种让浏览器能够在不重新加载整个网页的情况下,向后端发送请求并接收响应的技术(这样如果我们在登录一个网站的时候,如果输入错误信息,就不会将网页完全的重新加载一遍,导致账号密码需要完全重新输入,而是可能直接跳出一个提示之类的)

    ajax的特点:

    异步通信:发送请求后,页面不必一直等待响应,可以继续执行其他操作

    局部更新:只更新网页中需要变化的部分,不必重新加载整个页面

    减少不必要的数据传输:可以只请求当前需要的数据,而不必重新获取整个页面

    前后端交互:可以向后端接口发送请求,接收 JSON、文本等格式的数据

    ajax的基础语法:

    $(选择器).操作();

    常见写法举个例子:q

    $.ajax({
    url: "/user",
    type: "GET",
    data: { id: 1 },
    dataType: "json",

    success: function(res) {
    console.log(res);
    },

    error: function() {
    console.log("请求失败");
    }
    });

    前端用户登录的HTML代码(登录页面)

    解析一下这里的代码:

    我们通过表单填写的用户名以及密码,在我们的ajax中进行获取,就是data那一部分,前面是请求方式以及要交给的哪一个方法,就是前面的接口的路径(这里也体现了ajax的一个异步的特点,就是不是自己第一时间就返回响应,而是等待我们接口的返回再进行操作),接下来就是成功了(也就是正常返回了http响应,而不是说账号密码正确),这里的result就是前面传入的方法中返回的参数,我们的参数中不是定义了正确返回true,错误返回false,如果是true,就进行跳转其中location.href就是跳转的一种方式,错误就进行弹窗(alter)

    <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="jquery.min.js"></script>
    <script>
    function login() {
    $.ajax({
    type:"post",
    url:"/user/login",
    data:{
    userName:$("#userName").val(),
    password:$("#password").val()
    },
    success:function(result){
    if(result){
    //账号密码正确就跳转
    location.href="/index.html";
    }else{
    //错误的话就进行弹窗
    alert("账号密码错误");
    }
    }
    })
    }
    </script>
    </body>
    </html>

    正确的话就进行跳转页面,但是这个页面的代码我们还没有写

    前端显示用户名的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="jquery.min.js"></script>
    <script>
    $.ajax({
    type:"get",
    url:"user/getUsername",
    success:function(Username){
    $("#loginUser").text(Username)
    }
    })
    </script>
    </body>
    </html>

    写到这里我讲一下我之前的一个疑惑(关于session是怎么存储的):

    我们结合我的代码来理解就是当我们输入错误的时候,我们session中就不会保存name这个属性,当我们正确的时候才会保存,我们后端返回的页面跟session信息关系密切,我们会根据客户端所带的cookie中的sessionid来确认,如果是错误的话,我们后端拿到的session里面就压根没有存任何东西,所以返回的用户名也就是啥都没有的,但是正确时候拿到的sessionid得到的session就是有正确的name的,那我们会想:这个session的使用寿命或者范围是怎么来规定的呢,哪种情况会创建新的session

    场景

    通常会发生什么

    同一浏览器连续发送多个请求

    找到同一个 Session

    同一浏览器先登录失败,再登录成功

    原 Session 仍有效时,通常复用原 Session

    同一个 admin 换另一台电脑登录

    通常创建或使用另一个 Session

    Session 超时或被销毁后再次访问

    通常创建新的 Session

    两个人共用同一个浏览器和有效会话

    可能访问同一个 Session,不能仅凭 Session 区分实际操作者

    session是否会重新创建就是上面这张表所说的,所以我们写的代码的情况,session并不会更新,除非你等很长时间或者换一个浏览器,要不短时间在同一个浏览器中session是可能出现问题的,也就是说这个session并不能真正的确认用户是不是正确的,因为错误的话是不写,正确的话是写进去,也就代表了我们写完正确的之后,再写一个错误的,session里面还是存的正确时候的name,但是好在我们弹窗的判断是直接根据输入的是否正确,而不是看session,所以不会出现我上一次是正确的然后跳转,下一次我是错误的也跳转这种情况,但是session不做其他处理的话是“错误的”

    三,留言板

    我们需要创建一个留言板,里面包含从哪里来,对谁说以及说什么

    首先我们先创建后端接口,先是定义一个对象,里面包含我们要传输的数据,并且写出get和set方法,这些get和set方法每一次都写会很麻烦,我们可以通过引入一个依赖来简化我们的代码书写

    lombok

    这个方法可以帮我们简化一些东西,比如get,set方法,重写等方法,那如何进行引入呢

    方法一:在创建spring项目的时候勾选上lombok选项

    方法二:下载插件:EditStarters

    方法三:在pom文件里添加lombok相关依赖代码

    这里我们选择在第三种方式来添加

    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
    </dependency>

    怎么用:

    (直接引入后加注解就可以了)

    注解

    作用

    @Getter

    自动生成 Getter 方法,用于获取属性值

    @Setter

    自动生成 Setter 方法,用于修改属性值

    @ToString

    自动生成 toString() 方法,方便打印对象信息

    @EqualsAndHashCode

    自动生成 equals() 和 hashCode() 方法

    @Data

    综合注解,包含 Getter、Setter、ToString、EqualsAndHashCode 和 RequiredArgsConstructor 等功能

    后端留言以及拿取留言代码

    我们为了存储数据,一般是内存存储和外存(硬盘),这里我们选择内存,我们选择的是将数据存在list当中

    package com.example.demo;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.util.ArrayList;
    import java.util.List;
    @RestController
    @RequestMapping("/MessageController")
    public class MessageController {
    //我们将数据存放在内存中,也就是先写一个list存在里面
    List<MessageInfo>list=new ArrayList<>();
    //发布的接口
    @RequestMapping("/publish")
    public Boolean publish(@RequestBody MessageInfo messageInfo ){
    if (!StringUtils.hasLength(messageInfo.getFrom())||
    !StringUtils.hasLength(messageInfo.getTo())||
    !StringUtils.hasLength(messageInfo.getMes())){
    return false;
    }else {
    list.add(messageInfo);
    return true;
    }
    }
    //加载数据的接口
    @RequestMapping("/getmes")
    public List<MessageInfo> getmes(){
    return list;
    }
    }

    @RequestBody用来告诉 Spring MVC:从 HTTP 请求体中读取数据,并尝试将其转换成 Java 对象

    package com.example.demo;
    import lombok.Data;
    @Data
    public class MessageInfo {
    private String from;
    private String to;
    private String mes;
    }

    前端留言板代码

    <!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: 400px;
    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="jquery.min.js"></script>
    <script>
    getmes();
    function getmes(){
    $.ajax({
    type:"get",
    url:"MessageController/getmes",
    success:function(list){
    //成功就将列表遍历完写在下面
    for(let messageInfo of list){
    //2. 构造节点
    let divE = "<div>"+messageInfo.from +"对" + messageInfo.to + "说:" + messageInfo.mes+"</div>";
    //3. 把节点添加到页面上
    $(".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:"MessageController/publish",
    contentType:"application/json",
    data:JSON.stringify({
    from:from,
    to:to,
    mes: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("发表留言失败");
    }
    }
    })
    }

    </script>
    </body>

    </html>

    代码中这里前面的from,to,mes是我们后端的数据的命名,后面的那个是我们前端表格中获取的数据的名称

    这里的list是我们自己定义的一个变量名,接收ajax成功返回的数据,那么这个返回的也就是由所有留言组成的一个数组,每一个元素都是一整条的留言,下面这个messageInfo也是我们自己定义的,表示拿到的是一整条的留言,再下一行中就是拿到我们每一行留言中的每一个数据了,from,to,mes不是随便定义的,这个是看我们后端怎么命名的

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Spring MVC小案例(1)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!