当前位置: 首页 > news >正文

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>

相关文章:

  • 【Spring Boot】深度复盘在开发搜索引擎项目中重难点的整理,以及遇到的困难和总结
  • docker system prune命令详解
  • Docker安装Oracle11g数据库
  • 关于学习Go语言的并发编程
  • 嘴尚绝卤味:健康美味新选择,开启味蕾新旅程!
  • rust语言初识
  • phpstudy配置网站伪静态
  • 景源畅信电商:做抖音运营怎么开始第一步?
  • 循序渐进Docker Compose
  • SEC批准以太坊ETF了吗?
  • react 使用 Reducer 和 Context 进行纵向扩展
  • 安全攻防三
  • 29【PS 作图】宫灯 夜景转换
  • SCP收容物191~200
  • [Android]将私钥(.pk8)和公钥证书(.pem/.crt)合并成一个PKCS#12格式的密钥库文件
  • [nginx文档翻译系列] 控制nginx
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • Github访问慢解决办法
  • Git初体验
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • JavaScript 基础知识 - 入门篇(一)
  • Java反射-动态类加载和重新加载
  • java小心机(3)| 浅析finalize()
  • JSONP原理
  • Spring Cloud中负载均衡器概览
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 回顾2016
  • 基于游标的分页接口实现
  • 首页查询功能的一次实现过程
  • 想写好前端,先练好内功
  • 一个完整Java Web项目背后的密码
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • Python 之网络式编程
  • 阿里云服务器如何修改远程端口?
  • 移动端高清、多屏适配方案
  • ​HTTP与HTTPS:网络通信的安全卫士
  • !$boo在php中什么意思,php前戏
  • # .NET Framework中使用命名管道进行进程间通信
  • ###C语言程序设计-----C语言学习(3)#
  • #laravel 通过手动安装依赖PHPExcel#
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #每日一题合集#牛客JZ23-JZ33
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (javascript)再说document.body.scrollTop的使用问题
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (八十八)VFL语言初步 - 实现布局
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (算法)N皇后问题
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .