基于Springboot+Vue实现的在线答题闯关系统全过程

 更新时间:2024年12月09日 10:47:46   作者:无语小咪  
这篇文章主要介绍了基于Springboot+Vue实现的在线答题闯关系统的相关资料,文中包括前端Vue.js、后端SpringBoot及MySQL数据库的使用,系统功能涵盖顺序出题、体型练习、随机出题、错题本、收藏题和答题统计等,需要的朋友可以参考下

前言

本系统采用前后端分离架构,前端使用Vue.js框架实现,后端则通过Spring Boot进行构建,数据存储使用MySQL数据库。前端使用Vue.js进行数据渲染,而后端提供RESTful API接口来实现前后端的有效数据交互。

项目功能及技术

功能模块设计

  • 顺序出题模块:该模块允许用户按顺序答题,系统根据预设的题目顺序逐一展示给用户。用户完成每一道题后可以进入下一题,适合需要系统化学习的用户。

  • 体型练习模块:用户可以根据自己的需求选择特定的练习模式,比如选择某个类别或某个难度的题目进行练习。该模块支持用户自定义练习内容,帮助用户强化薄弱的知识点。

  • 随机出题模块:系统可以随机从题库中抽取题目,进行答题闯关,用户在有限的时间内答题,提升学习的趣味性和挑战性。

  • 错题本模块:该模块记录用户做错的题目,用户可以随时查看并重新进行练习,帮助用户集中攻克自己的薄弱环节,提升记忆与掌握度。

  • 我的收藏模块:用户可以将自己喜欢或难度较高的题目收藏到个人收藏夹,方便以后再次复习或挑战。

  • 答题统计模块:系统自动统计用户的答题情况,包括正确率、答题速度、错题数量等,帮助用户了解自己的学习进度和成效,并能根据数据调整学习策略。

技术:

  • Spring Boot:后端框架,利用Spring Boot的快速开发特性。同时,通过Mybatis简化数据库操作,提高数据访问效率。

  • Vue.js:前端框架,使用Vuex进行全局状态管理,提升数据的一致性与可维护性。

  • MySQL:数据库存储引擎,负责存储题目数据、用户答题记录、错题与收藏等信息。

  • Layui:前端UI组件库,用于搭建美观且响应式的用户界面,提升用户交互体验。

用户端

管理端

API

SpringBoot框架搭建

1.创建maven project,先创建一个名为SpringBootDemo的项目,选择【New Project】

然后在弹出的下图窗口中,选择左侧菜单的【New Project】

在project下创建module,点击右键选择【new】—【Module…】

左侧选择【Spring initializr】,通过idea中集成的Spring initializr工具进行spring boot项目的快速创建。窗口右侧:name可根据自己喜好设置,group和artifact和上面一样的规则,其他选项保持默认值即可,【next】

Developer Tools模块勾选【Spring Boot DevTools】,web模块勾选【Spring Web】,此时,一个Springboot项目已经搭建完成,可开发后续功能

实体映射创建Mapper

创建一个entity实体类文件夹,并在该文件夹下创建项目用到的实体类

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Data
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    private String account;

    private String pwd;

    private String userDesc;

    private String userHead;

    private LocalDateTime createTime;

    private Long role;

    private String nickname;

    private String email;

    private String tags;
}

接口封装

由于我们使用mybatis-plus,所以简单的增删改查不用自己写,框架自带了,只需要实现或者继承他的Mapper、Service

创建控制器Controller

整合Swagger

添加依赖

先导入spring boot的web包

<!--swagger依赖-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

配置Swagger

创建一个swagger的配置类,命名为SwaggerConfig.java

/*
     *用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本
     */
    private ApiInfo apiDemo() {
        return new ApiInfoBuilder()
                //用来自定义API的标题
                .title("SpringBoot项目SwaggerAPIAPI标题测试")
                //用来描述整体的API
                .description("SpringBoot项目SwaggerAPI描述测试")
                //创建人信息
                .contact(new Contact("测试员张三","http://localhost:8080/springboot/swagger-ui.html","xxxxxxxx@163.com"))
                //用于定义服务的域名
                //.termsOfServiceUrl("")
                .version("1.0") //可以用来定义版本
                .build();
    }

接口测试

运行Spring Boot项目,默认端口8080,通过地址栏访问url

接口组定义

根据不同的业务区分不同的接口组,使用@API来划分

@Api(tags = "用户管理") //  tags:组名称
@RestController
public class RoleController {
}

接口定义

使用@ApiModel来标注实体类,同时在接口中定义入参为实体类作为参数。

  • @ApiModel:用来标类

  • 常用配置项:value:实体类简称;description:实体类说明

  • @ApiModelProperty:用来描述类的字段的含义。

常用字段类型

字段类型所占字节存储范围最大存储值使用场景
TINYINT1-128~127127存储小整数
INT4-2147483648~21474836472147483647存储大整数
BIGINT8-9223372036854775808~92233720368547758079223372036854775807存储极大整数
DECIMAL可变长度存储精度要求高的数值
CHAR固定长度最多255字节255个字符存储长度固定的字符串
VARCHAR可变长度最多65535字节65535个字符存储长度不固定的字符串
DATETIME8‘1000-01-01 00:00:00’~‘9999-12-31 23:59:59’‘9999-12-31 23:59:59’存储日期和时间

参考代码块

  <body style="background-color: #f7f7f7;">
		<div class="headerBox">
			<div class="logoBox">
				<img src="img/logo1.png" />
				<div class="logoTitle">在线答题闯关</div>
			</div>
			<div class="menuBox">
				<div class="menuItem activeMenu ">
					<a href="index.html" rel="external nofollow"  rel="external nofollow" >练习模式</a>
				</div>
				<div class="menuItem blackColor">
					<a href="challengeLevels.html?param=primary" rel="external nofollow"  rel="external nofollow" >闯关模式</a>
				</div>
				<div class="menuItem blackColor">
					<a href="wrongQuestion.html" rel="external nofollow"  rel="external nofollow" >我的错题</a>
				</div>
				<div class="menuItem blackColor">
					<a href="myCollection.html" rel="external nofollow"  rel="external nofollow" >我的收藏</a>
				</div>
				<div class="menuItem blackColor">
					<a href="statistics.html" rel="external nofollow"  rel="external nofollow" >答题统计</a>
				</div>
				<div class="menuItem blackColor">
					<a href="center.html" rel="external nofollow"  rel="external nofollow" >个人中心</a>
				</div>
				<div class="menuItem blackColor">
					<a href="./login/login.html" rel="external nofollow"  rel="external nofollow" >退出登录</a>
				</div>
			</div>
		</div>
		<div class="container-fluid" id="content-page">
			<div class="row">
				<div class="col-md-2"> </div>
				<div class="col-md-8">
					<div class="searchBox">
						<div class="leftTitle">
							{{pageTitle}}
						</div>
					</div>
				</div>
				<div class="col-md-2"> </div>
			</div>
			<div class="row">
				<div class="col-md-2"> </div>
				<div class="col-md-8">
					<div v-for="(item,index) in questionList">
						<div class="radioItemBox" v-if="item.questionType == '单选题'">
							<div class="BtnBox radioItem">
								<div>{{index+1}}.</div>
								<textarea rows="18" cols="90" v-model="item.title" disabled></textarea>
								<img src="img/collecQues.png" class="radioItemTypeImg"
									v-on:click="collection(item.id)" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkA!=''">
								<div class="radioIconBox">
									<input type="radio" class="radioInputCheck" :name="index"
										v-on:change="checkOne(index,'A')" />
								</div>
								<div>A.</div>
								<input v-model="item.checkA" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkB!=''">
								<div class="radioIconBox">
									<input type="radio" class="radioInputCheck" :name="index"
										v-on:change="checkOne(index,'B')" />
								</div>
								<div>B.</div>
								<input v-model="item.checkB" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkC!=''">
								<div class="radioIconBox">
									<input type="radio" class="radioInputCheck" :name="index"
										v-on:change="checkOne(index,'C')" />
								</div>
								<div>C.</div>
								<input v-model="item.checkC" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkD!=''">
								<div class="radioIconBox">
									<input type="radio" class="radioInputCheck" :name="index"
										v-on:change="checkOne(index,'D')" />
								</div>
								<div>D.</div>
								<input v-model="item.checkD" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkE!=''">
								<div class="radioIconBox">
									<input type="radio" class="radioInputCheck" :name="index"
										v-on:change="checkOne(index,'E')" />
								</div>
								<div>E.</div>
								<input v-model="item.checkE" disabled class="radioLineV2Input" />
							</div>
						</div>
						<div class="radioItemBox" v-if="item.questionType == '多选题'">
							<div class="BtnBox radioItem">
								<div>{{index+1}}.</div>
								<textarea rows="18" cols="90" v-model="item.title" disabled></textarea>
								<img src="img/collecQues.png" class="radioItemTypeImg"
									v-on:click="collection(item.id)" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkA!=''">
								<div class="radioIconBox">
									<input type="checkbox" class="radioInputCheck" :name="index"
										v-on:change="checkTwo($event,index,'A')" />
								</div>
								<div>A.</div>
								<input v-model="item.checkA" disabled class="radioLineV2Input" />
							</div>

							<div class="BtnBox radioLineV2" v-if="item.checkB!=''">
								<div class="radioIconBox">
									<input type="checkbox" class="radioInputCheck" :name="index"
										v-on:change="checkTwo($event,index,'B')" />
								</div>
								<div>B.</div>
								<input v-model="item.checkB" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkC!=''">
								<div class="radioIconBox">
									<input type="checkbox" class="radioInputCheck" :name="index"
										v-on:change="checkTwo($event,index,'C')" />
								</div>
								<div>C.</div>
								<input v-model="item.checkC" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkD!=''">
								<div class="radioIconBox">
									<input type="checkbox" class="radioInputCheck" :name="index"
										v-on:change="checkTwo($event,index,'D')" />
								</div>
								<div>D.</div>
								<input v-model="item.checkD" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkE!=''">
								<div class="radioIconBox">
									<input type="checkbox" class="radioInputCheck" :name="index"
										v-on:change="checkTwo($event,index,'E')" />
								</div>
								<div>E.</div>
								<input v-model="item.checkE" disabled class="radioLineV2Input" />
							</div>
						</div>
						<div class="radioItemBox" v-if="item.questionType == '判断题'">
							<div class="BtnBox radioItem">
								<div>{{index+1}}.</div>
								<textarea rows="18" cols="90" v-model="item.title" disabled></textarea>
								<img src="img/collecQues.png" class="radioItemTypeImg"
									v-on:click="collection(item.id)" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkA!=''">
								<div class="radioIconBox">
									<input type="radio" class="radioInputCheck" :name="index"
										v-on:change="checkOne(index,'A')" />
								</div>
								<div>A.</div>
								<input v-model="item.checkA" disabled class="radioLineV2Input" />
							</div>
							<div class="BtnBox radioLineV2" v-if="item.checkB!=''">
								<div class="radioIconBox">
									<input type="radio" class="radioInputCheck" :name="index"
										v-on:change="checkOne(index,'B')" />
								</div>
								<div>B.</div>
								<input v-model="item.checkB" disabled class="radioLineV2Input" />
							</div>
						</div>
					</div>

					<div class="BtnBox margin-sm">
						<div class="AddQuesBtnItem" v-on:click="SaveChange">
							<img src="img/submit.png" />
							提交
						</div>
						<div style="height:100px;"></div>
					</div>
				</div>
				<div class="col-md-2"> </div>
			</div>
		</div>
		<script type="text/javascript" src="js/jquery.min.js"></script>
		<script type="text/javascript" src="js/vue.js"></script>
		<script type="text/javascript" src="login/layui/layui.js"></script>
		<script>
			//轻量级框架
			var dataInfo = new Vue({
				el: "#content-page",
				//Vue的数据对象
				data: {
					questionList: [],
					pageTitle: ''
				}, //数据对象结束
				//方法
				methods: {
					GetAll: function() {
						let vm = this;
						let param = GetQueryString("param");
						let type = GetQueryString("type");
						let quesType = '';
						if (param == 'practice') {

							if (type == '0') {
								quesType = '单选题';
							} else if (type == '1') {
								quesType = '多选题';
							} else {
								quesType = '判断题';
							}
							vm.pageTitle = '练习模式:' + quesType;
						} else if (param == 'order') {
							vm.pageTitle = '顺序出题';
						} else {
							vm.pageTitle = '随机练习';
						}
						var user = JSON.parse(sessionStorage.getItem('user'));

						$.ajax({
							url: "http://127.0.0.1:8081/common/answer-list?userId=" + user.id + "&param=" +
								param + "&type=" + quesType,
							async: false,
							type: "POST",
							contentType: 'application/json',
							dataType: 'json',
							success: function(json) {

								vm.questionList = json.list
							}

						});

					},
					//单选框选择事件
					checkOne(index, check) {
						let vm = this;
						vm.questionList[index].isChecked = check;
					},
					//多选框选择事件
					checkTwo(event, index, check) {
						let vm = this;
						const checked = event.target.checked;
						let info = vm.questionList[index];
						let checkedArray = info.isChecked.split(',');
						if (checkedArray[0] == '') {
							checkedArray.splice(0, 1);
						}
						if (checked) {
							checkedArray.push(check);
							info.isChecked = checkedArray.join(',');
						} else {
							let ind = checkedArray.indexOf(check);
							if (ind !== -1) {
								checkedArray.splice(ind, 1);
							}
							info.isChecked = checkedArray.join(',');
						}
					},
					//点击提交
					SaveChange() {
						let vm = this;
						//得分
						let number = 0;
						let list = vm.questionList;
						for (let i = 0; i < list.length; i++) {
							if (list[i].isChecked != '') {
								let right = list[i].rightKey.split(',');
								let check = list[i].isChecked.split(',');
								if (right.length === check.length && right.sort().toString() === check.sort()
									.toString()) {
									list[i].correct = 1;
									number++;
								}
							}
						}
						var user = JSON.parse(sessionStorage.getItem('user'));
						var vo = {};
						vo.answerList = list;
						vo.number = number;
						vo.userId = user.id;
						vo.type = '练习';
						$.ajax({
							url: "http://127.0.0.1:8081/common/get-answer",
							async: false,
							type: "POST",
							contentType: 'application/json',
							dataType: 'json',
							data: JSON.stringify(vo),
							success: function(json) {
								layui.use('layer', function() {
									var layer = layui.layer;

									// 弹出提示框
									layer.msg('您的分数为:' + number + '分', {
										icon: 6, // 图标样式,默认为信息图标
										time: 2000, // 显示时间,默认为2秒
										shade: 0.5, // 遮罩层透明度,默认为0.3
										shadeClose: true // 是否点击遮罩关闭弹框,默认为true
									});
								});
							}
						});


					},
					//点击收藏
					collection(id) {
						var vo = {};
						var user = JSON.parse(sessionStorage.getItem('user'));
						vo.userId = user.id;
						vo.answerId = id;
						$.ajax({
							url: "http://127.0.0.1:8081/common/addCollect",
							async: false,
							type: "POST",
							contentType: 'application/json',
							dataType: 'json',
							data: JSON.stringify(vo),
							success: function(json) {
								layui.use('layer', function() {
									var layer = layui.layer;

									// 弹出提示框
									layer.msg(json.returnMsg, {
										icon: json.returnMsg == '您已收藏过' ? 5 :
										6, // 图标样式,默认为信息图标
										time: 2000, // 显示时间,默认为2秒
										shade: 0.5, // 遮罩层透明度,默认为0.3
										shadeClose: true // 是否点击遮罩关闭弹框,默认为true
									});
								});
							}
						});

					},

				}, //方法结束
				created: function() {
					var vm = this;
					vm.GetAll();
				}, //初始加载方法结束

			}); //vue结束

			function GetQueryString(name) {
				var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
				var r = window.location.search.substr(1).match(reg);
				if (r != null) return unescape(r[2]);
				return null;
			}
		</script>
	</body>
</html>
<head>
		<meta charset="utf-8" />
		<title>答题统计</title>
	</head>
	<link href="css/index.css" rel="external nofollow"  rel="stylesheet" />
	<link href="css/bootstrap.min.css" rel="external nofollow"  rel="stylesheet" />
	<body style="background-color: #f7f7f7;">
		<div class="headerBox">
			<div class="logoBox">
				<img src="img/logo1.png" />
				<div class="logoTitle">在线答题闯关</div>
			</div>
			<div class="menuBox">
				<div class="menuItem  blackColor">
					<a href="index.html" rel="external nofollow"  rel="external nofollow" >练习模式</a>
				</div>
				<div class="menuItem blackColor">
					<a href="challengeLevels.html?param=primary" rel="external nofollow"  rel="external nofollow" >闯关模式</a>
				</div>
				<div class="menuItem blackColor">
					<a href="wrongQuestion.html" rel="external nofollow"  rel="external nofollow" >我的错题</a>
				</div>
				<div class="menuItem blackColor">
					<a href="myCollection.html" rel="external nofollow"  rel="external nofollow" >我的收藏</a>
				</div>
				<div class="menuItem activeMenu">
					<a href="statistics.html" rel="external nofollow"  rel="external nofollow" >答题统计</a>
				</div>
				<div class="menuItem blackColor">
					<a href="center.html" rel="external nofollow"  rel="external nofollow" >个人中心</a>
				</div>
				<div class="menuItem blackColor">
					<a href="./login/login.html" rel="external nofollow"  rel="external nofollow" >退出登录</a>
				</div>
			</div>
		</div>
		<div class="container-fluid" id="content-page">
			<div class="row">
				<div class="col-md-2"> </div>
				<div class="col-md-8">
					<div class="searchBox">
						<div class="leftTitle">
							答题统计
						</div>
						<div>

						</div>
					</div>
				</div>
				<div class="col-md-2"> </div>
			</div>
			<div class="row">
				<div class="col-md-2"> </div>
				<div class="col-md-4">
					<div id="main"></div>
				</div>
				<div class="col-md-4">
					<div id="main2"></div>
				</div>
				<div class="col-md-2"> </div>
			</div>
		</div>
		<script type="text/javascript" src="js/jquery.min.js"></script>
		<script type="text/javascript" src="js/echarts.min.js"></script>
		<script>
			function GetQueryString(name) {
				var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
				var r = window.location.search.substr(1).match(reg);
				if (r != null) return unescape(r[2]);
				return null;
			}


			var user = JSON.parse(sessionStorage.getItem('user'));
			$.ajax({
				url: "http://127.0.0.1:8081/common/total?userId=" + user.id,
				async: false,
				type: "POST",
				contentType: 'application/json',
				dataType: 'json',
				data: JSON.stringify({}),
				success: function(json) {

					initCharts1(json.data);
					var inputArray = json.data;
					// 定义对应的题目类型名称数组
					var typeNameArray = ['单选题', '多选题', '判断题'];
					
					// 结果数组
					var resultArray = [];
					
					// 遍历输入数组
					for (var i = 0; i < inputArray.length; i++) {
					    // 构造对象,并添加到结果数组中
					    var item = {
					        value: inputArray[i],
					        name: typeNameArray[i]
					    };
					    resultArray.push(item);
					}
					initCharts(resultArray);
				}
			});


			function initCharts(data1) {
				var chartDom = document.getElementById('main');
				var myChart = echarts.init(chartDom);
				var option;
				option = {
					title: {
						text: '答题数统计',
						subtext: '',
						left: 'center'
					},
					tooltip: {
						trigger: 'item'
					},
					legend: {
						orient: 'vertical',
						left: 'left'
					},
					series: [{
						name: 'Access From',
						type: 'pie',
						radius: '50%',
						data: data1,
						emphasis: {
							itemStyle: {
								shadowBlur: 10,
								shadowOffsetX: 0,
								shadowColor: 'rgba(0, 0, 0, 0.5)'
							}
						}
					}]
				};
				myChart.setOption(option);
			};

			function initCharts1(data2) {
				var chartDom = document.getElementById('main2');
				var myChart = echarts.init(chartDom);
				var option;

				option = {
					xAxis: {
						type: 'category',
						data: ['单选题', '多选题', '判断题']
					},
					yAxis: {
						type: 'value'
					},
					series: [{
						data: data2,
						type: 'bar',
						showBackground: true,
						backgroundStyle: {
							color: 'rgba(180, 180, 180, 0.2)'
						}
					}]
				};

				myChart.setOption(option);
			};
		</script>
	</body>
</html>

总结 

到此这篇关于基于Springboot+Vue实现的在线答题闯关系统的文章就介绍到这了,更多相关Springboot+Vue在线答题闯关系统内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • ssm项目session使用及其作用域问题

    ssm项目session使用及其作用域问题

    这篇文章主要介绍了ssm项目session使用及其作用域问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • Java日期工具类操作字符串Date和LocalDate互转

    Java日期工具类操作字符串Date和LocalDate互转

    这篇文章主要介绍了Java日期工具类操作字符串Date和LocalDate互转,文章首先通过需要先引入坐标展开主题的相关内容介绍,需要的朋友可以参一下
    2022-06-06
  • JavaSE面试题之this与super关键字的区别详解

    JavaSE面试题之this与super关键字的区别详解

    this关键字用于引用当前对象的引用,super关键字用于引用父类对象的引用,下面这篇文章主要给大家介绍了关于JavaSE面试题之this与super关键字区别的相关资料,需要的朋友可以参考下
    2023-12-12
  • springboot实现定时任务的四种方式小结

    springboot实现定时任务的四种方式小结

    本文主要介绍了springboot实现定时任务的四种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • Mybatis-Plus查询中如何排除标识字段

    Mybatis-Plus查询中如何排除标识字段

    这篇文章主要介绍了Mybatis-Plus查询中排除标识字段的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 微信小程序微信登录的实现方法详解(JAVA后台)

    微信小程序微信登录的实现方法详解(JAVA后台)

    通常我们在登录微信小程序的时候都是通过授权登录,下面这篇文章主要给大家介绍了关于微信小程序微信登录的实现方法,文中通过实例代码介绍的介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • java中添加按钮并添加响应事件的方法(推荐)

    java中添加按钮并添加响应事件的方法(推荐)

    下面小编就为大家带来一篇java中添加按钮并添加响应事件的方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • 浅谈Sharding-JDBC强制路由案例实战

    浅谈Sharding-JDBC强制路由案例实战

    本文主要介绍了浅谈Sharding-JDBC强制路由案例实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Spring+MongoDB实现登录注册功能

    Spring+MongoDB实现登录注册功能

    这篇文章主要为大家详细介绍了Spring+MongoDB实现登录注册功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • java使用RSA工具进行信息加解密

    java使用RSA工具进行信息加解密

    我们在开发中需要对用户敏感数据进行加解密,比如密码等信息,这篇文章主要为大家详细介绍了java如何使用RSA工具进行信息加解密,感兴趣的小伙伴可以了解下
    2023-12-12

最新评论