Spring web mvc入门练习

news2025/1/18 13:57:56

对于Spring方面的知识重在多练习

目录

一、计算器

1、前端界面

2、约定前后端交互接口

3、服务器代码

二、用户登录

前端代码

服务器代码

三、留言板

后端代码

前端代码


一、计算器

我们需要通过前后端的交互最终完成这样的界面以及完成需求

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
接口描述计算两个数的和

请求参数

类型变量名
Integernum1
Integer

num2

响应数据

Content-typehtml

这样我们的接口文档就完成了,接口文档的格式是自己定义的,目的是让客户端能看懂就好

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
接口描述校验密码是否正确

请求参数

passwordString
usernameString

响应数据

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数据

urlMessage/getList
响应Json格式

 发表新留言也为Json格式

urlMessage/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

感谢观看

道阻且长,行则将至

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2132540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows系统离线搭建darknet

没有网的情况下采用将安装包全部都下载下来&#xff0c;再安装的方式。darknet在windows上编译问题比较多&#xff0c;经历了3天的踩坑&#xff0c;终于搭建好。。。下面简单记录一下安装过程。 1.下载cuda,cudnn,anaconda,opencv,opencv_python&#xff0c;vs。安装顺序&…

[Redis] Redis中的Hash类型和List类型

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

CISP-PTE CMS sqlgun靶场渗透测试

1.打开靶场 2.在搜索框尝试xss <script>alert(1)</script> 发现此处存在xss漏洞 3.在搜索框尝试sql注入 -1 union select 1,2,3# 发现页面有回显 4.查询数据库名 -1 union select 1,database(),3# 5.查询数据库的所有表 -1 union select 1,(select group_conc…

Matlab做二阶函数

关于解答&#xff1a; >> % Expert PID Control % 二阶传递函数的阶跃响应 % 位置式 clc; clear all; close all;n500; % 设置离散点的个数 Ts0.001; % 设置离散的采样时间 epsilon0.001; …

剪辑视频怎么放慢速度?6种方法可以轻易做到

在这个快节奏的短视频时代&#xff0c;视频编辑中的慢动作效果往往能吸引观众的眼球&#xff0c;赋予画面以独特的艺术感和情感深度。但是很多小伙伴不知道该怎么将视频播放速度放缓&#xff0c;今天&#xff0c;给大家分享6种剪辑视频放慢速度的高效方法&#xff0c;一起来学习…

【物理编程】解决物理压力的正确画法

这里写自定义目录标题 压力的画法 压力的画法 该程序是一个交互式的教育工具&#xff0c;它通过可视化的方式帮助学生和教师理解多边形的几何特性以及力的表示方法。以下是该程序的一些优点和对教师的帮助&#xff0c;用专业的语言进行总结&#xff1a; 增强理解力&#xff1a…

98、RS485全自动收发电路入坑笔记

因为RS485采用叉分信号&#xff0c;只支持半双工。正常的RS485芯片驱动电路是需要GPIO来切换发送和接收模式。如下图所示&#xff0c;一般的RS485电平转换芯片都有RE/DE脚&#xff0c;用来切换收发模式。 例如这篇推荐&#xff1a;芯片RS485自动收发电路常见问题与应对策略 但…

【kubernetes】Ingress和Ingress-Controller介绍,高可用应用案例

一&#xff0c;Ingress介绍 Ingress是k8s中一种重要的资源对象&#xff0c;它主要用于定义从集群外部到集群内部服务的HTTP(S)路由规则。用于管理代理 Ingress-Controller的配置文件。 kubectl explain ingress二&#xff0c;Ingress-Controller介绍 Ingress Controller 是 …

[ESP32]:如何在micropython中添加C库

[ESP32]&#xff1a;如何在micropython中添加C库 本文将描述如何在micropython中添加一个基于c语言的led模块。 1.编写c驱动 选择一个目录&#xff1a;examples/usercmodule&#xff0c;建立对应的驱动文件hw_led&#xff1a; . ├── cexample │ ├── examplemodule…

RAG 在企业应用中落地的难点与创新分享

在2024稀土开发者大会-AI Agent与应用创新分会上&#xff0c;我有幸分享了我们团队在企业应用中实施RAG&#xff08;检索增强生成&#xff09;的难点与创新。希望通过这篇文章&#xff0c;与大家探讨我们在实践中遇到的问题和解决方案&#xff0c;为从事相关工作的朋友提供一些…

Spring2-入门

目录 入门案例 案例分析 Log4j2日志框架 Log4j2日志概述 引入依赖 加入日志配置文件 使用日志 入门案例 1.引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi&qu…

技术速递|VS Code Java 8月更新 - 重要 Gradle 更新!用户体验与入门向导增强

作者&#xff1a;Nick Zhu 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code for Java 八月更新&#xff01;在这篇博客中&#xff0c;我们将涵盖重要 Gradle 更新、更多用户体验改进以及更好的入门体验&#xff0c;马上开始吧&#xff01; Gradle 更…

eclipse配置maven

eclipse配置maven 启动 Eclipse&#xff0c;转到 Window > Preferences 在左侧导航栏中&#xff0c;展开 Maven 节点。 在 User Settings 下&#xff0c;单击 Add。 浏览到 Maven 安装目录中 conf/settings.xml 文件。 在 Global Settings 下&#xff0c;单击 Add。 浏览到…

详解Diffusion扩散模型:理论、架构与实现

本文深入探讨了Diffusion扩散模型的概念、架构设计与算法实现&#xff0c;详细解析了模型的前向与逆向过程、编码器与解码器的设计、网络结构与训练过程&#xff0c;结合PyTorch代码示例&#xff0c;提供全面的技术指导。 关注TechLead&#xff0c;复旦AI博士&#xff0c;分享A…

【三】TDengine 3.3.2 生产级别集群搭建

TDengine 3.3.2 集群搭建 集群规划 一、主机名和端口规划 修改主机信息&#xff1a;修改hosts信息&#xff0c;TDEngine是通过FQDN进行访问&#xff0c; 规划好三个节点对应的hostname。 vi /etc/hosts 追加以下信息 192.168.90.131 node1 192.168.90.132 node2 192.168.90.133…

IV转换放大器原理图及PCB设计分析

【前言】 今天给大家分享一下关于IV转换放大器的相关电路设计心得。IV转换使用的场合非常之多&#xff0c;尤其是电流型输出的传感器&#xff0c;比如光敏二极管、硅光电池等等&#xff0c;这些传感器输出的电流信号非常微弱&#xff0c;我们如果需要检测它们&#xff0c;首先得…

springboot013基于SpringBoot的旅游网站的设计与实现

&#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345; 一 、设计说明 1.1 课题开发的背…

android 老项目中用到的jar包不存在,通过离线的方法加载

1、之前的项目用的jar包&#xff0c;已经不在远程仓库中&#xff0c;只能手工去下载&#xff0c;并且安装。 // implementation com.github.nostra13:Android-Universal-Image-Loader // implementation com.github.lecho:hellocharts-android:v1.5.8 这…

Java-数据结构-二叉树-习题(一) (✪ω✪)

文本目录&#xff1a; ❄️一、习题一(检查两颗树是否相同)&#xff1a; ▶ 思路&#xff1a; ▶ 代码&#xff1a; ❄️二、习题二(另一棵树的子树)&#xff1a; ▶ 思路&#xff1a; ▶ 代码&#xff1a; ❄️三、习题三(翻转二叉树)&#xff1a; ▶ 思路&#xff1a; ▶ 代…

【C++】STL容器-string的遍历

1.引言 C STL&#xff08;Standard Template Library&#xff09;作为C标准库的核心部分&#xff0c;其重要性不言而喻。它提供了一系列高效、灵活且可复用的数据结构和算法&#xff0c;极大地提升了开发效率&#xff0c;并使得代码更加易于阅读和维护。 在STL中&#xff0c;…