Java研学-RBAC权限控制(七)

八 表单验证

1 Bootstrap-validator

  Bootstrap-validator是一个基于 Bootstrap 的表单验证插件,它可以帮助开发者更方便地进行表单验证,提高用户体验。
① 引入插件

<!--引入验证插件的样式文件--><link rel="stylesheet" href="/static/js/plugins/bootstrap-validator/css/bootstrapValidator.min.css"/><link rel="stylesheet" href="/static/js/plugins/bootstrap-treeview/bootstrap-treeview.min.css"/>
<!--引入验证插件的js文件--><script type="text/javascript" src="/static/js/plugins/bootstrap-validator/js/bootstrapValidator.min.js"></script>
<!--中文语言库--><script type="text/javascript" src="/static/js/plugins/bootstrap-validator/js/language/zh_CN.js"></script>

2 更新前端页面的表单验证规则 – /employee/input

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>员工管理</title>
</head>
<body class="hold-transition skin-black sidebar-mini"><div th:replace="common/fragment :: link"></div><div class="wrapper"><div th:replace="common/fragment :: navbar"></div><div th:replace="common/fragment :: menu"></div><div class="content-wrapper"><section class="content-header"><h1>员工编辑</h1></section><section class="content"><div class="box"><form class="form-horizontal" action="/employee/saveOrUpdate" method="post" id="editForm" ><input type="hidden" name="id" th:value="${employee?.id}"><div class="form-group" style="margin-top: 10px;"><label class="col-sm-2 control-label">用户名:</label><div class="col-sm-6"><input type="text" class="form-control" th:disabled="${employee != null}" th:value="${employee?.username}" name="username" placeholder="请输入用户名"></div></div><div class="form-group" style="margin-top: 10px;"><label class="col-sm-2 control-label" >真实姓名:</label><div class="col-sm-6"><input type="text" class="form-control" name="name" th:value="${employee?.name}" placeholder="请输入真实姓名"></div></div><div class="form-group" th:if="${employee == null}"><label for="password" class="col-sm-2 control-label">密码:</label><div class="col-sm-6"><input type="password" class="form-control" id="password" name="password" placeholder="请输入密码"></div></div><div class="form-group" th:if="${employee == null}"><label for="repassword" class="col-sm-2 control-label">验证密码:</label><div class="col-sm-6"><input type="password" class="form-control" id="repassword" name="repassword" placeholder="再输入一遍密码"></div></div><div class="form-group"><label for="email" class="col-sm-2 control-label">电子邮箱:</label><div class="col-sm-6"><input type="text" th:value="${employee?.email}" class="form-control" id="email" name="email" placeholder="请输入邮箱"></div></div><div class="form-group"><label for="age" class="col-sm-2 control-label">年龄:</label><div class="col-sm-6"><input type="text" class="form-control" th:value="${employee?.age}" id="age" name="age" placeholder="请输入年龄"></div></div><div class="form-group"><label for="dept" class="col-sm-2 control-label">部门:</label><div class="col-sm-6"><select class="form-control" id="dept" name="dept.id"><option value="">请选择</option><option th:each="department:${departments}"th:text="${department.name}"th:value="${department.id}"th:selected="${department.id == employee?.dept?.id}"></option></select></div></div><div class="form-group" id="adminDiv"><label for="admin" class="col-sm-2 control-label">超级管理员:</label><div class="col-sm-6" style="margin-left: 15px;"><input type="checkbox" id="admin" th:checked="${employee?.admin}" name="admin" class="checkbox" ></div></div><div class="form-group" id="roleDiv"><label for="role" class="col-sm-2 control-label">分配角色:</label><br/><div class="row" style="margin-top: 10px"><div class="col-sm-2 col-sm-offset-2"><select multiple class="form-control allRoles" id="role" style="height: 350px;" size="15"><option th:each="role:${roles}"th:text="${role.name}"th:value="${role.id}"></option></select></div><div class="col-sm-1" style="margin-top: 60px;" align="center"><div><a type="button" class="btn btn-primary  " style="margin-top: 10px" title="右移动"onclick="moveSelected('allRoles', 'selfRoles')"><span class="glyphicon glyphicon-menu-right"></span></a></div><div><a type="button" class="btn btn-primary " style="margin-top: 10px" title="左移动"onclick="moveSelected('selfRoles', 'allRoles')"><span class="glyphicon glyphicon-menu-left"></span></a></div><div><a type="button" class="btn btn-primary " style="margin-top: 10px" title="全右移动"onclick="moveAll('allRoles', 'selfRoles')"><span class="glyphicon glyphicon-forward"></span></a></div><div><a type="button" class="btn btn-primary " style="margin-top: 10px" title="全左移动"onclick="moveAll('selfRoles', 'allRoles')"><span class="glyphicon glyphicon-backward"></span></a></div></div><div class="col-sm-2"><select multiple class="form-control selfRoles" style="height: 350px;" size="15" name="roleIds"><option th:each="role:${selfRoles}"th:text="${role.name}"th:value="${role.id}"></option></select></div></div></div><div class="form-group"><div class="col-sm-offset-1 col-sm-6"><button type="submit" class="btn btn-primary btn-submit">保存</button><a href="javascript:window.history.back()" class="btn btn-danger">取消</a></div></div></form></div></section></div><div th:replace="common/fragment :: footer"></div></div><script>// 全部左右移动function moveAll(src, target) {$('.' + target).append($('.' + src + ' > option'));}// 选中左右移动function moveSelected(src, target) {$('.' + target).append($('.' + src + ' > option:selected'));}// 点击保存按钮/* $('.btn-submit').click(function () {$('.selfRoles > option').prop('selected',true);$('#editForm').submit();})*/$(function () {// 下拉列表去重var arr = $('.selfRoles > option').map(function (index, domEle) {return $(domEle).val();})$('.allRoles > option').each(function (i, e) {// 判断每次遍历的元素是否在上面的数组中出现过?if($.inArray($(e).val(),arr) >= 0){// 若存在则返回索引,说明重复了。我们要将该元素删除$(e).remove();}})// 回显超级管理员则需要隐藏下面的 divif($('#admin').prop('checked')){// 是选中状态,说明是超级管理员,需要隐藏下面角色部分$('#roleDiv').addClass('hidden');} else {// 不是选中状态,说明不是超级管理员,需要显示下面角色部分$('#roleDiv').removeClass('hidden')}})// 点击超级管理员按钮隐藏角色部分$('#admin').click(function () {// 判断勾选状态if($(this).prop('checked')){// 是选中状态,说明是超级管理员,需要隐藏下面角色部分$('#roleDiv').addClass('hidden');} else {// 不是选中状态,说明不是超级管理员,需要显示下面角色部分$('#roleDiv').removeClass('hidden')}})</script><script>$("#editForm").bootstrapValidator({/*找到表单 调用插件*/feedbackIcons: { // 图标valid: 'glyphicon glyphicon-ok',/*对号图标*/invalid: 'glyphicon glyphicon-remove',/*错号图标*/validating: 'glyphicon glyphicon-refresh'/*转圈图标*/},fields:{ // 配置要验证的字段 开始验证username:{validators:{ // 验证的规则//message:"用户名必填",notEmpty:{ // 不能为空message:"用户名必填" // 错误时的提示信息 若这一层没有message则向上找validators层没有则再次向上找message},stringLength: { // 字符串的长度范围min: 1,max: 10,message:"用户名长度为1~5位"},regexp: {//正则表达式regexp: /^[a-zA-Z0-9_\.]+$/,message: '禁止使用非法字符'},remote:{//远程校验 验证用户是否存在 可以添加延迟减少访问数据库次数type:'post',url:'/employee/checkUsername',message:'用户名已存在'}}},name:{validators:{ // 验证的规则notEmpty:{ // 不能为空message:"姓名必填" // 错误时的提示信息},stringLength: { // 字符串的长度范围min: 1,max: 5,message:"昵称长度为1~5位"}}},password:{validators:{notEmpty:{ // 不能为空message:"密码必填" // 错误时的提示信息},different: {field: 'username',message: '用户名与密码不能相同'}}},repassword:{validators:{notEmpty:{ // 不能为空message:"密码必填" // 错误时的提示信息},identical: {// 两个字段的值必须相同field: 'password',message: '两次输入的密码必须相同'},}},email: {validators: {emailAddress: {}, // 邮箱格式message:"请输入正确邮箱"}},age:{validators: {between: { // 数字的范围min: 18,max: 60,message:"非法年龄范围"}}}}}).on('success.form.bv', function(e) {// 阻止表单提交 原先button的selected操作挪到了这里 依然选中后再提交 监听表单 点击submit才会进入到这里e.preventDefault();$('.selfRoles > option').prop('selected', 'true');// TODO 这里可以改成用异步的方式提交表单$.post("/employee/saveOrUpdate",$('#editForm').serialize(),/*通过serialize()获取表单所有数据将其转换为一条String语句*/function (data) {/*只有状态码为200才能走进function 当200缺插入失败才叫插入失败 这里是成功之后的回调函数*/if(data.success){// 插入成功 展示页面location.href='/employee/list'} else {/*插入失败跳模式框*/Swal.fire({text: data.msg,icon:'error',confirmButtonText: '确定!',});}})});</script>
</body>
</html>

3 验证添加的员工是否存在 – 用户名不能重复

  ① 前端代码

$("#editForm").bootstrapValidator({/*找到表单 调用插件*/feedbackIcons: { // 图标valid: 'glyphicon glyphicon-ok',/*对号图标*/invalid: 'glyphicon glyphicon-remove',/*错号图标*/validating: 'glyphicon glyphicon-refresh'/*转圈图标*/},fields:{ // 配置要验证的字段 开始验证username:{validators:{ // 验证的规则//message:"用户名必填",notEmpty:{ // 不能为空message:"用户名必填" },stringLength: { // 字符串的长度范围min: 1,max: 10,message:"用户名长度为1~5位"},regexp: {//正则表达式regexp: /^[a-zA-Z0-9_\.]+$/,message: '禁止使用非法字符'},remote:{//远程校验 验证用户是否存在 可以添加延迟减少访问数据库次数type:'post',url:'/employee/checkUsername',message:'用户名已存在'delay: 1000, // 输入内容延迟 1 秒后发请求}}},
// 略

  ② 后端代码,插件要求返回结果需要为键值对形式 key 为 valid,value 为 boolean 类型(使用 Map 封装即可)
  valid: true 代表验证通过(该用户名不存在)
  valid: false 代表验证不通过(用户名已经存在)

// 检查用户名是否存在 (Controller)@RequestMapping("/checkUsername")@ResponseBodypublic Map<String,Boolean> checkUsername(String username){Map<String,Boolean> map = new HashMap<>();Boolean flag = employeeService.checkUsername(username);map.put("valid",flag);return map;}// service
Boolean checkUsername(String username);
// impl
public Boolean checkUsername(String username) {Integer count = employeeMapper.checkUsername(username);return count==0;
}

  ③ Mapper,可以通过count()方法查询数据库中有无该用户名,有返回1,无返回0

// 接口
Integer checkUsername(String username);
// xml
<select id="checkUsername" resultType="java.lang.Integer">select count(*) from employee where username=#{username}
</select>

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

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

相关文章

docker中安装jenkins,并在node和cloud上跑通基于源码控制SCM的pipeline

目录 一、摘要 二、部署和使用 1. docker部署jenkins 1.1 准备数据目录 1.2 拉取jenkins镜像并启动 1.3 初始化配置 1.3.1 登录容器查看初始化密码 1.3.2 访问jenkins并输入初始化密码 1.3.3 创建管理员账户 1.3.4 初始化完成 2. jenkins使用之多分支流水线 2.1 准…

Java解决用@value从配置文件中给静态变量赋值的问题

问题描述 value放在实例变量上会生效&#xff0c;放在静态变量上不会生效&#xff0c;原因是Value是在bean实例化的时候进行属性赋值的&#xff0c;而静态变量是在类进行初始化的时候赋值的。 解决思路 可以在进行实例初始化的时候&#xff0c;将静态变量赋值。 解决方案 目前…

EI会议的录用通知和后续步骤是什么?

收到EI会议的录用通知后&#xff0c;通常会有一系列后续步骤&#xff0c;以下是一般的流程&#xff1a; 1. 录用通知 确认录用通知&#xff1a;在收到录用通知后&#xff0c;仔细阅读通知内容&#xff0c;确认你的论文已经被会议录用。查看详细信息&#xff1a;录用通知中通常…

WPF中DataGrid实现多选框功能

1. 效果图 2. Model建立 public class RstModelCheck : ObservableObject {//为了显示Head1和Head2.而且View中绑定属性而非字段&#xff0c;否则不能显示。public string? Name { get; set; } public bool PlatenAll {get > _platenAll;set{SetProperty(ref _platenAl…

Python实现将LabelMe生成的JSON格式转换成YOLOv8支持的TXT格式

标注工具 LabelMe 生成的标注文件为JSON格式&#xff0c;而YOLOv8中支持的为TXT文件格式。以下Python代码实现3个功能&#xff1a; 1.将JSON格式转换成TXT格式&#xff1b; 2.将数据集进行随机拆分&#xff0c;生成YOLOv8支持的目录结构&#xff1b; 3.生成YOLOv8支持的YAML文件…

基于EBAZ4205矿板的图像处理:07sobel边缘检测算法

基于EBAZ4205矿板的图像处理&#xff1a;07sobel边缘检测算法 项目文件 随后会上传项目全部文件&#xff0c;和之前一样免费下载 先看效果 如上所见&#xff0c;能够提取图像的边缘&#xff0c;这个sobel边缘检测算法的阈值&#xff08;认定是否为边缘的阈值&#xff09;一样…

C++入门 基于ros的话题通信

一、 开发环境 ubuntu20.04 ros版本noetic 参考视频 https://www.bilibili.com/video/BV1Ci4y1L7ZZ/?p52&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_source4cd1b6f268e2a29a11bea5d2568836ee 二、 创建两个功能包 //创建工作空间 工作空…

英伟达:AI之火还在燃烧!

昨晚&#xff0c;全球市场屏息以待的一家公司财报终于发布了&#xff0c;没有超出大家预期的是&#xff0c;他还是超预期了。 大家当然都知道我们要说的是——英伟达&#xff01; 如今&#xff0c;全球大模型之Z激Z正酣&#xff0c;AI芯片装备竞赛需求猛烈&#xff0c;作为AI…

浅析智能体开发(第二部分):智能体设计模式和软件架构

大语言模型&#xff08;LLM&#xff09;驱动的智能体&#xff08;AI Agent&#xff09;展现出许多传统软件所不具备的特征。不仅与传统软件的设计理念、方法、工具和技术栈有显著的差异&#xff0c;AI原生&#xff08;AI Native&#xff09;的智能体还融入了多种新概念和技术。…

外汇天眼:塞舌尔券商JustMarkets被控为诈骗平台,众多交易纠纷背后的真相究竟为何?

近年来外汇市场因为具有高流动性、交易时间长、不容易被操控等特色&#xff0c;受到愈来愈多投资人重视&#xff0c;相关交易愈来愈火热。外汇天眼身为全球最权威的经纪商查询平台&#xff0c;不仅致力于收录交易商信息&#xff0c;也经常发布券商解析与测评文章。最近我们发现…

IDEA 自定义注解(类注释、方法注释)

一、生成类注释 1、打开设置位置 打开File —> Settings —> Editor —> File and Code Templates —> Files —> Class 2、将自定义的类注解规则&#xff0c;复制到Class中。 /** * * 功能: * * 作者: 暗自着迷 * * 日期: ${YEAR}-${MONTH}-${DAY} ${HOU…

3D 高斯泼溅(Gaussian Splatting)-3D重建的3DGS时代

3D重建自从NeRfs出现之后又热闹了一次&#xff0c;3D GS技术一时间燃变了整个三维重建和Slam领域&#xff0c;几个月不见&#xff0c;沧海桑田。 NeRF貌似已成为过去式&#xff0c;三维重建进入了3DGS时代&#xff0c;且3DGS在各方面比NeRF落地更快。3D 高斯泼溅&#xff08;S…

React里面useMemo和useCallBack的区别

useMemo 和 useCallback 接收的参数都是一样&#xff0c;第一个参数为回调&#xff0c;第二个参数为要依赖的数据。 相同部分&#xff1a;都是依赖数据发生变化&#xff0c;才会去更新缓存数据 不同部分&#xff1a; useMemo缓存的是二次计算的数据&#xff0c;主要用于缓存…

加密与解密(第四版)】第二十四章笔记

第二十四章 .NET平台加密解密 暂时不看 https://learn.microsoft.com/zh-cn/dotnet/core/introduction https://www.cnblogs.com/1996V/p/9037603.html https://zhuanlan.zhihu.com/p/134174688

Docker-数据卷的挂载

文章目录 数据卷概念数据卷实现机制数据卷特性数据卷操作数据卷挂载通用命令匿名挂载具名挂载数据卷继承容器数据卷只读容器数据卷读写-默认 总结 数据卷概念 为了很好的实现数据保存和数据共享&#xff0c;Docker提出了Volume这个概念&#xff0c;简单的说就是绕过默认的联合文…

Java(十)---抽象类和接口

文章目录 前言知识回顾1.抽象类1.1.抽象类语法1.2 抽象类特性 2.接口2.1.接口的概念2.2 语法规则2.3 接口使用2.4 接口特性2.5 实现多个接口 3.Object类3.1 获取对象信息3.2.对象比较equals方法 4.接口使用实例4.1.Comparable4.2.Comparator4.3.Cloneable深拷贝和浅拷贝 前言 …

Flutter 中的 Scaffold 小部件:全面指南

Flutter 中的 Scaffold 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;Scaffold 是一个非常重要的 widget&#xff0c;它为 Material Design 中的布局提供了一个基础的结构。Scaffold 通常作为应用的主要布局容器&#xff0c;提供了管理应用栏&#xff08;AppBar&…

新定义RD8T36P48点亮LED--汇编

其实汇编和C语言差不多&#xff0c;简单的东西用汇编挺好&#xff0c;中等及以上复杂度的程序还是C语言更灵活 直接在keil新建好工程&#xff0c;选好芯片型号和下载方式&#xff0c;再创建一个.asm文件并添加到工程&#xff0c; 工程创建完如图 工程配置 代码 ORG 0000HL…

两数交换,数组查找奇数个数的数(位运算)

文章目录 一、异或运算&#xff1a;1.1 Demo1.2 面试题 一、异或运算&#xff1a; 1.1 Demo 0和N进行异或运算都等于N 任何一个数和自己异或运算都等于0 且异或运算满足交换率 a^b b^a eg&#xff1a; a 甲 &#xff0c; b 已 那么则有 a a^b ​ b a^b ​ a a^b 故有&am…

如何理解数字孪生?数字孪生三维可视化有什么关系?

随着科技的飞速发展和数字化转型的浪潮&#xff0c;数字孪生技术逐渐崭露头角&#xff0c;并在多个领域展现出巨大的潜力。而在这股技术革新的潮流中&#xff0c;数字孪生三维可视化以其直观、精确和动态的特点&#xff0c;成为了推动数字化转型的重要部分。 一、数字孪生的魅…