1)用户管理项目:基本功能介绍
1)登录功能:只能是管理员登录,普通用户无法进行登录
因为普通用户进行登陆之后有信息泄露的风险,况且来说你普通用户登陆之后给你分配权限也没有什么用呀,想要操作什么?
2)用户分页列表页面:普通用户的列表页和超级管理员的列表页,可以修改普通用户和超管
3)条件查询:组合条件查询,不定规则的查询,指定名称,指定籍贯,指定邮箱来进行查询
4)分页功能:前端用户信息显示分页功能
5)添加用户:但是可以新增管理员
6)单条删除功能,多条删除功能(选中多条进行删除),管理员不可以删除管理员
7)修改用户:管理员不可以操作管理员(修改,删除)
8)多条批量删除用户
用动态标签,判断里面是否有管理员,如果有管理员,是不能删除的
注意:
1)这个系统只能是管理员来进行使用,普通用户无法进行操作此系统;
2)管理员可以添加管理员和普通用户,但是管理员不可以删除,修改管理员;
2)设计数据库:
使用的技术:SpringBoot+Mybatis+SpringMVC/拦截器/统一数据格式的返回/统一常的处理
用户表:
UserID 用户的唯一身份标识 int
登录名 varchar(100),
姓名 Varchar(50)
性别 varchar(10)
年龄 int
籍贯 varchar(50)
QQ varchar(15)
邮箱 varchar(50)是否是超级管理员,int
登录名 varchar(50),不允许有中文的
密码 varchar(100)
用户创建时间 varchar(50)
用户修改时间 varchar(50)
数据库插入操作:
drop database if exists Java100; create database if not Java100 character set utf8; use Java100; create table User( userID int primary key auto_increment, userName varchar(50) unique not null, loginName varchar(60) unique not null, passWord varchar(90) unique not null, sex varchar(30) default "男", address varchar(60), qq varchar(60), email varchar(40), isAdmin int default 0, createTime datetime default Now(), updateTime datetime default Now() );
引入依赖:
1)SpringBootDevTools
2)Lombok
3)SpringWeb
4)MyBatisFrameWork
5)MySQL Dirver
6)拦截器
3)配置配置文件:
#下面是配置数据库连接的基本信息 spring.datasource.username=root spring.datasource.url=jdbc:mysql://127.0.0.1:3306/Java100?characterEncoding=utf-8&useSSL=true spring.datasource.password=12503487 spring.driver-class-name=com.mysql.cj.jdbc.Driver #下面是配置数据库XML文件的保存路径 mybatis.mapper-locations=classpath:mapper/**Mapper.xml #配置MyBatis打印的SQL logging.level.com.example.demo=debug mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
我们在配置文件里面指定了mapper的xml文件的路径,在我们的xml里面,我们通过namespace指定了被mapper修饰的接口的路径
4)对同一的异常进行处理,对于统一的对全局生效的文件,我们可以把它放在Configuration文件里面
/对统一的异常进行处理 @ControllerAdvice public class ProcessException { @ExceptionHandler(Exception.class) @ResponseBody public HashMap<String,Object> Start(Exception e){ //我们这一次返回的是JSON格式的数据 HashMap<String,Object> hashMap=new HashMap<>(); hashMap.put("status",200); hashMap.put("data",""); hashMap.put("state",-1); hashMap.put("message",e.getMessage()); return hashMap; } }
5)返回原则:所有的接口必须有统一的数据格式返回
我们要想进行统一的数据格式的返回,方法有两种:
1)定义一个全局的返回对象,每一个接口返回的时候调用该对象来进行返回
2)Advice接口增强实现统一的数据封装
返回JSON格式的数据: { status:状态码 data:后端返回的数据 state:-1/1 message:是对status返回状态的一个对应声明,比如说登陆失败,用户名密码错误,用户名密码是空 }
6)配置拦截器
public class ProcessLogin implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //如果这个方法的返回值是true,那么表示当前用户已经登陆,那么直接可以访问目标方法 //如果说这个方法的返回值是false,那么表示当前用户没有进行登录,那么会直接跳转到登陆界面 HttpSession httpSession= request.getSession(false); if(httpSession==null||httpSession.equals("")||httpSession.getAttribute("user")==null||httpSession.getAttribute("user").equals("")){ response.sendRedirect("login.html"); return false; } return true; } } //把这个注册到Spring里面 @Configuration class InsertSpringBoot implements WebMvcConfigurer{ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new ProcessLogin()) .addPathPatterns("/**") .excludePathPatterns("/css/**") .excludePathPatterns("/fonts/**") .excludePathPatterns("/images/**") .excludePathPatterns("/js/**") .excludePathPatterns("/css/**") .excludePathPatterns("/**/login.html"); } }
7)将所有的前端文件放在static目录下面
8)根据数据库的表创建实体类
@Data public class UserInfo { private int userID; private String userName; private String passWord; private String sex; private String address; private String qq; private String email; private String isAdmin; private Timestamp createTime; private Timestamp updateTime; }
9)除此之外,咱们还要向数据库中插入一条记录,表示超级管理员
1.实现登录功能:我们要根据前端传递的用户名和密码来进行实现登陆
1.1)约定前后端交互的接口:
POST /login submit ContentType:application/json;charset=utf-8 body: { "userName":"A", "passWord":"12503487" } 后端返回: 200 OK HTTP/1.1 true/false true表示登陆成功,false表示登陆失败
1.2)前端代码:
<div class="form-group"> <label for="username">用户名:</label> <input type="text" name="user" class="form-control" id="username" placeholder="请输入用户名"/> </div> <div class="form-group"> <label for="password">密码:</label> <input type="password" name="password" class="form-control" id="password" placeholder="请输入密码"/> </div> <hr/> <div class="form-group" style="text-align: center;"><!--class="form-group"--> <input style="width: 200px;height: 40px" id="submit" class="btn btn btn-primary" type="button" value="登录" onclick="mysub()"> </div>
先写前端的JS代码:
<script> function mysub(){ //1.先获取到前端的控件,在进行获取到控件里面的值,千万不要忘写# var username=jQuery("#username"); var password=jQuery("#password"); //2.判断里面的值是否为空,否则重新进行登录 //注意这里面要注意不能写成jQuery(username.val())==null,括号不能忘写,一定要在电脑点击之后 //进行获取到控件 if(jQuery.trim(username.val())==""){ alert("请先输入用户名"); username.focus(); return; } if(jQuery.trim(password.val())==""){ alert("请输入密码"); password.focus(); return; } jQuery.ajax({ url:"Java100/login", type:"POST", contentType:"application/json;charset=utf-8", data:JSON.stringify({"userName":username.val(),"passWord":password.val()}), success:function(data,status){ if(data.data==true){//注意着里面的"true"不可以写成字符串里面的格式 alert("登陆成功"); location.assign("list.html") }else{ alert("登陆失败"); } } }); } </script>
1.2)先写XML里面的代码,在写Mapper里面的代码,在写UserService里面的代码,最后写Controller里面的代码:
package com.example.demo.Controller; import com.example.demo.Model.UserInfo; import com.example.demo.Service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @Controller public class UserController { @Autowired private UserService userService; @RequestMapping("/Java100/login") @ResponseBody public Boolean login(@RequestBody UserInfo userInfo, HttpServletRequest req){ //1.进行非空校验,必须传递用户名和密码 Logger logger= LoggerFactory.getLogger(UserController.class); logger.info(String.valueOf(userInfo)); if(userInfo.getUserName()==null||userInfo.getPassWord()==null||userInfo.getPassWord().equals("")||userInfo.getUserName().equals("")) { return false; } //代码走到这里说明参数校验合格 UserInfo ReturnUserInfo= userService.login(userInfo); if(ReturnUserInfo==null||ReturnUserInfo.equals("")){ return false; } //2.登陆成功,设置HttpSession对象 HttpSession httpSession= req.getSession(true); httpSession.setAttribute("user",ReturnUserInfo); return true; } } //<select id="login" resultType="com.example.demo.Model.UserInfo"> // select * from UserInfo where userName=#{userName} and passWord=#{passWord} and //isAdmin=1 // </select>
2.实现展示功能:
前端推荐学习网站:https://v2.cn.vuejs.org/v2/guide/#Vue-js-%E6%98%AF%E4%BB%80%E4%B9%88
前端代码:
<table border="1" class="table table-bordered table-hover" id="info">//父亲属性 <tbody> <tr class="success"> <th>选择</th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>超管</th> <th>操作</th> </tr> <tr v-for="userInfo in userInfos"> //循环这里面的每一个元素userInfo //因为tr标签里面的每一个标签都是td标签所以这么写可以更规范一些 <td> <input type="checkbox" v-bind:id=userInfo.userID> //下面这个是绑定id属性 </td> <th>{{userInfo.userID}}</th> <td>{{userInfo.userName}}</td> <td>{{userInfo.sex}}</td> <td>{{userInfo.age}}</td> <td>{{userInfo.address}}</td> <td>{{userInfo.qq}}</td> <td>{{userInfo.email}}</td> //三目运算符要放在双大括号里面 <td>{{userInfo.isAdmin==true?"是":"否"}}</td> <td> <a class="btn btn-default btn-sm" v-bind:src="`update.html?userID=${userInfo.userID}`">修改</a> <a class="btn btn-default btn-sm" v-bind:src="`delete?userID=${userInfo.userID}`">删除</a> </td> </tr> <!-- <tr> <td>{{userInfos}}</td> <td>{{userInfos[0]}}</td> </tr> --> </tbody> </table> <div> <nav aria-label="Page navigation"> <ul id="all" class="pagination"> <li class="active"><a href="javascript:void(0);">1</a></li> <li><a href="javascript:void(0);">2</a></li> <li><a href="javascript:void(0);">3</a></li> <li><a href="javascript:void(0);" aria-label="Next"> <span aria-hidden="true">»</span></a> </li> <span style="font-size: 20px;margin-left: 10px;"> 共 10 条记录,共 1 页 </span> </ul> </nav> </div> </div>
实现前后端交互的逻辑:
<script> var app=new Vue({ el:"#info", data(){ return{ userInfos:[{ "userID":2,"userName":"李佳伟","loginName":null, "passWord":"admin","sex":"男","address":"内蒙古赤峰市敖汉旗", "qq":"3430296778","email":"139.com","isAdmin":"0","createTime":"2022-11-16T04:30:38.000+00:00", "updateTime":"2022-11-16T04:30:38.000+00:00"}] } }, methods:{ GetAll(){ $.ajax({ type:"GET", url:"Java100/GetAll", context:this, success:function(data,status){ console.log(typeof data.data); console.log(data,status); app.userInfos= data.data; console.log(app.userInfos); } }); } } }); // app.GetAll();
后端代码:
//得到所有用户信息 @RequestMapping("/GetAll") public List<UserInfo> GetAll(){ return userService.GetAll(); }
3.实现添加用户:用户名是不能重复的,所以要在数据库里面的用户名是不能重复的,要添加唯一约束,unique,但是如果说有一天数据工程师把你的表约束给改了,不是unquiue了,那么你需要在你的程序里面进行验证用户名是否重复了
//1.进行非空校验 //2.将数据添加到数据库里面,普通用户没法进行新增操作,但是有的人会说, //普通用户不是不能登陆吗?但是最好进行校验一下(获取登陆者的isAdmin从session中进行获取) //3.判断用户名是否重复(从数据库中查询这个用户名对应的用户) //4.进行数据库添加操作 Controller只能和Service进行交互,Service只能和Mapper交互,可不敢在Controller里面即进行调用Service里面的代码,还可以进行调用Mapper里面的代码
//添加用户 @RequestMapping("/addUser") public int addUser(@RequestBody UserInfo userInfo,HttpServletRequest req){ //1.进行非空校验,也可以进行检验前端传递的所有参数是否为空 if(userInfo==null|| !StringUtils.hasLength(userInfo.getUserName())||!StringUtils.hasLength(userInfo.getPassWord())){ System.out.println("前段参数为空"); return -1; } //2.普通用户没法进行新增操作,但是有的人会说,普通用户不是不能登陆吗?但是最好进行校验一下当前进行新增用户的人是否是普通管理员 HttpSession httpSession=req.getSession(false); UserInfo LoginUser= (UserInfo) httpSession.getAttribute("user"); if(httpSession==null||httpSession.equals("")||LoginUser==null||LoginUser.equals("")||LoginUser.getIsAdmin()==0){ System.out.println("没有进行登录"); return -1; } //3.判断用户名是否重复,直接进行传递一个前段传递的username看看能否在数据库中查询到,如果查询到用户说明是用户名重复 UserInfo nameUserInfo=userService.SelectByUserName(userInfo.getUserName()); if(nameUserInfo!=null){ System.out.println("用户名重复"); return -1; } //4.进行数据库添加操作 int len= userService.addUserInfo(userInfo); if(len==1){ return 1; }else{ System.out.println("插入失败"); return -1; } }
10)实现添加功能
1)在我们的前端直接获取到用户名,密码,确认密码,年龄,QQ,邮箱,判断他们是否为空,检测密码和确认密码是否一致
2)将这些参数传递到我们的后端,添加操作成功了,我们就返回一个1,失败我们就返回一个数字-1
3)在这里面我们还是要注意,我们的有几个控件
注意:QQ字段和email字段是非必传字段,所以我们在后端使用动态标签的方式来进行添加
2.1)比如说我们想要获取到性别这样的控件(input type=radio)
<input id="man" type="radio" name="sex" value="男" checked="checked">男 <input id="women" type="radio" name="sex" value="女">女 当我们的单选框中的name属性一样的时候,我们才可以进行单选
该怎们进行实现呢?
针对上面的控件:
jQuery("input[name=sex]:checked").val(); 1)先通过name=sex来进行获取到input的radio控件 2)checked拿到选中的控件 3)val()方法可以拿到性别信息是因为input里面有value属性
2.2)我们还要要拿到籍贯的控件:select标签,里面有id属性
<select name="address" id="address" class="form-control"> <option value="北京">北京</option> <option value="上海">上海</option> <option value="广州">广州</option> </select> jQuery("#address").val-----针对select标签来进行设置 根据id来进行取值
当我们的用户进行添加操作的时候,后端在继续进行插入的时候,如果前端请求的参数User对象,当User对象的IdAdmin是1的时候,表明当前用户是管理员,他要进行添加管理员操作,我们要验证当前登录的用户是否是管理员!!!!我们就通过HttpSession中的Session对象来进行判断:
<div class="form-group" id="adminDiv" style="display: none;"> <label for="email">管理员:</label> <input id="admin_yes" type="radio" name="isadmin" value="1"/>是 <input id="admin_no" type="radio" name="isadmin" value="0" checked="checked"/>否 </div> //上面有一个display:none的属性表示不会进行显示里面的内容
前端代码:向那些非必传的参数直接进行获取到val()就可以了,但是仍然进行校验的比如说用户名和密码,我们还是需要先获取到控件的
div class="form-group" style="text-align: center"> <input id="btn_sub" class="btn btn-primary" type="button" value="提交" onclick="mysub()"/> <input id="btn_back" class="btn btn-default" type="button" value="返回" onclick="location.href='list.html'"/> </div> <script> function mysub(){ var username=jQuery("#username"); var password=jQuery("#password"); var password2=jQuery("#password2"); var sex=jQuery("input[name=sex]:checked").val(); var age=jQuery("#age").val(); var address=jQuery("#address").val(); var qq=jQuery("#qq").val(); var email=jQuery("#email").val(); var isAdmin=jQuery("input[name=isadmin]:checked").val();//这里面表示被添加为用户的认识否是超级管理员 //1.对于那些需要进行登录权限的,先获取到控件,对于那些不需要进行监测的,直接获取到内容 //1.先进行校验用户名和密码是否为空,还有确认密码 if(jQuery.trim(username.val())==""){ alert("用户名为空"); username.focus(); return; } if(jQuery.trim(password.val())==""){ alert("您当前输入的密码是空"); username.focus(); return; } if(jQuery.trim(password2.val())==""){ alert("您当前输入的确认密码是空"); username.focus(); return; } //2.判断密码和确认密码是否相同 if(jQuery.trim(password.val())!=jQuery.trim(password2.val())){ alert("您当前输入的密码和确认密码不相同"); username.focus(); return; } //3.向后端发送添加用户的请求 $.ajax({ type:"POST", url:"Java100/addUser", contentType:"application/json;charset=utf-8", data:JSON.stringify( { "userName":username.val(), "passWord":password.val(), "sex":sex, "age":age, "address":address, "qq":qq, "email":email, "isAdmin":isAdmin, } ), success:function(data,status){ if(data!=null&&data.data>0){ alert("恭喜添加成功"); if(confirm("是否继续添加?")){ location.href=location.href; }else{ location.href="list.html"; } }else{ alert("您的用户名重复"); } } }); }
后端:
1)vue循环渲染标签问题,开发者工具+抓包
2)我在自己做项目的时候不小心把where语句加到trim标签里面了
<insert id="addUserInfo"> insert into UserInfo(userID,userName,passWord, <if test="sex!=null">sex,</if> <if test="age!=null">age,</if> <if test="address!=null">address,</if> <if test="qq!=null">qq,</if> <if test="email!=null">email,</if> <if test="isAdmin!=null">isAdmin,</if> createTime, updateTime) values(null,#{userName},#{passWord}, <if test="sex!=null">#{sex},</if> <if test="age!=null">#{age},</if> <if test="address!=null">#{address},</if> <if test="qq!=null">#{qq},</if> <if test="email!=null">#{email},</if> <if test="isAdmin!=null">#{isAdmin},</if> Now(), Now()) </insert>
<insert id="InsertOneUser"> insert into user(userID, <if test="username!=null"> username, </if> <if test="password!=null"> password, </if> <if test="sex!=null"> sex, </if> <if test="address!=null"> address, </if> <if test="qq!=null"> qq, </if> <if test="email!=null"> email, </if> <if test="isadmin!=null"> isadmin, </if> createtime,updatetime) values( null, <if test="username!=null"> #{username}, </if> <if test="password!=null"> #{password}, </if> <if test="sex!=null"> #{sex}, </if> <if test="address!=null"> #{address}, </if> <if test="qq!=null"> #{qq}, </if> <if test="email!=null"> #{email}, </if> <if test="isadmin!=null"> #{isadmin}, </if> NOW(), NOW()) </insert>
//3.新增用户 @RequestMapping("/addUser") @ResponseBody public boolean addUser(@RequestBody User user,HttpServletRequest req){ //1.校验当前添加用户的人是否是超级管理员,从Session中获取到User对象,User对象就是当前进行新增用户的人 //虽然只有超级管理员能够登录,但是如果恶意人员绕过前端的JS跳过直接打给后端 HttpSession session=req.getSession(false); User loginuser= (User) session.getAttribute("user"); if(loginuser.getIsadmin()==0){ return false; } //2.检测前端传递的参数是否正确 if(!StringUtils.hasLength(user.getUsername())||!StringUtils.hasLength(user.getPassword())||!StringUtils.hasLength(user.getSex())){ return false; } //3.进行添加操作 userMapper.addUser(user); return true; }
10)实现修改操作:这个修改页面向后端发送了两次HTTP请求
1)在首页点击了对应用户的修改操作,进入到对应用户的修改页面,所以在加载update.html
前端要向后端发送一个HTTP请求,获取到对应的用户信息并展示在对应的位置;
2)于是用户开始进行修改页面信息,进行点击提交按钮之后进行修改;
1)从我们的url中获取到UserID(前端),根据location.search来进行查询:
在前端传递的url形如:127.0.0.1:8080/Java100?userID=1&password=120
在前端拿到的location.search=?userID=1&password=120
错误代码 getParamValue(); function getParamValue(){ //获取到前端的url参数 var value=""; var queryString=location.search; if(location.search==null){ return ""; } var querys=queryString.substring(1,queryString.length);//这个操作是去掉queryString中的? console.log(querys); var kvs=querys.split("&"); for(let data of kvs){ var str=data.substring("="); for(let message of str){ if(message=="userID"){ return str[1]; } } return ""; } }
写一个方法获取到url里里面的参数 function getParamValue(){ //获取到前端的url参数 var value=""; var queryString=location.search; if(location.search==null){ return ""; } var querys=queryString.substring(1,queryString.length);//这个操作是去掉queryString中的? var kvs=querys.split("&");//此时的kvs就是一个数组 for(let i=0;i<kvs.length;i++){//kvs->key=1&value=2那么接下来的kv就是key=1 var kv=kvs[i].split("=");//此时的kv就是一个数组 if(kv[0]=="userID"){ return kv[1]; } } return ""; }
2)向后端发送ajax请求,展示信息(展示用户信息,浏览器进行循环拼接页面)
var address=jQuery("#address").val(); var qq=jQuery("#qq").val(); var email=jQuery("email").val(); userID=getParamValue(); if(userID>0){//当前参数是有效的,前端传递的userID //这个请求在页面进行加载的时候就已经发送了 $.ajax({ url:"Java100/GetUserInfoByUserID?userID="+userID, type:"GET", success:function(data,status){ if(data!=null||data.data!=null&&data.userID>0){ //开始进行把数据循环拼接到页面上面 //拼接用户名 jQuery("#username").val(data.data.userName); //拼接密码 jQuery("#password").val(data.data.passWord); //拼接性别 if(data.data.sex=="女"){ jQuery("#women").attr("checked","checked"); }else{ jQuery("#women").attr("checked","checked"); } //拼接年龄 jQuery("#age").val(data.data.age); //拼接籍贯 jQuery("#address").val(data.data.address); //拼接QQ jQuery("#qq").val(data.data.qq); //拼接email jQuery("#email").val(data.data.email); //看看是否是管理员 if(data.data.isAdmin==0){ jQuery("#admin_no").attr("checked","checked"); }else{ jQuery("#admin_yes").attr("checked","checked"); } }else{ alert("后端接口不可用"); } } }); }else{ Console.log("非法参数"); } //可写可不写 function getParamValue(){ //获取到前端的url参数 var value=""; var queryString=location.search; if(location.search==null){ return ""; } var querys=queryString.substring(1,queryString.length);//这个操作是去掉queryString中的? var kvs=querys.split("&"); for(let i=0;i<kvs.length;i++){//kvs->key=1&value=2那么接下来的kv就是key=1 var kv=kvs[i].split("="); if(kv[0]=="userID"){ return kv[1]; } } return ""; } </script>
3)用户进行编辑信息再去提交信息(这时候又发送了一个ajax请求)
涉及到的安全问题:
再进行展示页面的时候先要获得用户登录权限的校验,还有查看权限的校验普通用户是不能进行编辑超级管理员的信息的
在进行编辑和提交信息的时候也是要做上面两个步骤的校验
后端代码:
1)进行查询指定用户并进行浏览器循环渲染在页面的代码:
//根据userID来向数据库拉取数据到更新用户的前端页面 @RequestMapping("/GetUserInfoByUserID") public UserInfo GetUserInfoByUserID(Integer userID) { //1.判断前端的参数是否合法 if(userID==null||userID.equals("")||userID<0){ return null; } //2.进行查找数据 return userService.GetUserInfoByUserID(userID); }
2)当用户进行二次提交之后成功的服务器修改页面的代码:
//更新用户的信息对应的后端代码 @RequestMapping("/updateUserInfo") public int updateUserInfo(@RequestBody UserInfo userInfo,HttpServletRequest req){ //1.这个和用户登录十分相似,先做前端参数的校验 if(userInfo==null||userInfo.getUserName()==null||userInfo.getPassWord()==null||userInfo.getUserName().equals("")||userInfo.getPassWord().equals("")) { logger.info("当前用户没有进行登录"); return -1; } //2.判断用户是否进行登录,并看看当前登录的人是不是超级管理员,并且查看一下用户名是否重复了 HttpSession httpSession=req.getSession(false); if(httpSession==null||httpSession.getAttribute("user")==null){ return -1; }else{ //查看当前用户是否是管理员 UserInfo LoginUserInfo= (UserInfo) httpSession.getAttribute("user"); if(LoginUserInfo.getIsAdmin()==0){ logger.info("您当前不是超级管理员,无法进行登录进行修改用户操作"); return -1; } UserInfo userNameInfo=userService.SelectByUserName(userInfo.getUserName()); } //3.进行用户更新操作 return userService.updateUserInfo(userInfo); }
<update id="updateUserInfo"> update userInfo set <trim suffixOverrides=","> <if test="userName!=null"> userName=#{userName}, </if> <if test="passWord!=null"> passWord=#{passWord}, </if> <if test="sex!=null"> sex=#{sex}, </if> <if test="age!=null"> age=#{age}, </if> <if test="address!=null"> address=#{address}, </if> <if test="qq!=null"> qq=#{qq}, </if> <if test="email!=null"> email=#{email}, </if> <if test="isAdmin!=null"> isAdmin=#{isAdmin}, </if> </trim> where userName=#{userName} </update>
“attr() 方法设置或返回被选元素的属性值。定义和用法根据该方法不同的参数,其工作方式也有所差异。当该方法用于返回属性值,则返回第一个匹配元素的值。当该方法用于设置属性值,则为匹配元素设置一个或多个属性/值对
confrim方法里面写一个句子,页面显示,就可以实现是否要执行这个句子
11)实现单条用户删除功能:
进行删除的时候需要进行额外判断不能把自己删除掉,就是检查前端传过来的userID不能和httpSession中存放的userID相同
//前端:之前是这样写的:<a class="btn btn-default btn-sm" v-bind:href="`Java100/deleteUserInfo?userID=${userInfo.userID}`">删除</a> 后端: @RequestMapping("/deleteUserInfo") public int deleteUserInfo(Integer userID, HttpServletResponse resp) throws IOException { if(userID==null||userID.equals("")){ System.out.println("当前前段传递的userID为空"); return -1; } //这里最好判断一下当前进行修改的人是否是管理员 userService.deleteUserInfo(userID); //跳转到列表页 return 1; }
但是后来发现无法实现页面跳转功能,所以咱们还是使用点击事件的方法来进行传递删除操作:
前端代码:<button class="btn btn-default btn-sm" v-bind:onclick="`deleteUser(${userInfo.userID})`">删除</button> 前端发送ajax请求的代码: <script> function deleteUser(userID){ $.ajax({ type:"GET", url:"Java100/deleteUserInfo?userID="+userID, success:function(data,status){ if(data!=null&&data.data!=null&&data.data==1){ alert("删除成功"); location.href=location.href; }else{ alert("后端接口返回数据失败"+data.message) } } }); } </script>
@RequestMapping("/deleteUserInfo") public int deleteUserInfo(Integer userID, HttpServletResponse resp) throws IOException { if(userID==null||userID.equals("")){ System.out.println("当前前段传递的userID为空"); return -1; } //这里最好判断一下当前进行修改的人是否是管理员 userService.deleteUserInfo(userID); //跳转到列表页 return 1; } }
12)多组删除:
当进行多条删除的时候,咱们是选中页面中的按钮,有多个按钮可以提供选中
<input type="checkbox" v-bind:id=userInfo.userID> //这个每一行里面都有一个checkbox选中框(每一个用户对应一行都有一个选中框)
拿一个控件的属性:attr(属性名字)和prop(属性名字),况且attr一般用于静态属性
1)要想办法拿到所有的checkBox获取到里面的ID属性传递到后端
页面布局:
<table border="1" class="table table-bordered table-hover" id="info"> <tbody> <td class="success"> <th>选择</th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>籍贯</th> <th>QQ</th> <th>邮箱</th> <th>超管</th> <th>操作</th> </td> <tr v-for="userInfo in userInfos" id="user"> <th> <input type="checkbox" v-bind:id=userInfo.userID class="thHHHH"> </th> <td>{{userInfo.userID}}</td> <td>{{userInfo.userName}}</td> <td>{{userInfo.sex}}</td> <td>{{userInfo.age}}</td> <td>{{userInfo.address}}</td> <td>{{userInfo.qq}}</td> <td>{{userInfo.email}}</td> <td>{{userInfo.isAdmin==true?"是":"否"}}</td> <td> <a class="btn btn-default btn-sm" v-bind:href="`update.html?userID=${userInfo.userID}`">修改</a> <button class="btn btn-default btn-sm" v-bind:onclick="`deleteUser(${userInfo.userID})`">删除</button> </td> </tr> <!-- <tr> <td>{{userInfos}}</td> <td>{{userInfos[0]}}</td> </tr> --> </tbody>
function del(){ if(confirm("确认删除吗?")){ let arr1=""; jQuery("#info").find("tr").each( function(i){ if(jQuery(this).find("th:first").find("input").prop("checked")==true){ alert(jQuery(this).find("input").attr("id")); arr1=arr1+jQuery(this).find("input").attr("id")+","; //每一次拼接id都用,进行分割 } }); if(arr1!=null){ //1.进行截取从0号位置到倒数第一个位置进行截取字符串 arr1=arr1.substring(0,arr1.length-1);//1,2,3,4 //2.进行使用,来进行分割变成一个纯数字的数组 // arr1=arr1.split(","); //3.进行发送ajax请求 $.ajax({ type:"POST", url:"Java100/deleteAll", data:{"listInteger":arr1}, success:function(data,status){ if(data.data>0){ alert("删除成功") location.href=location.href; }else{ alert("删除失败"+data.message); location.hred=location.href; } } }); }else{ alert("当前什么也没有进行选中呀"); } } } </script>
1)jQuery("#info")是拿到id属性是info的HTML标签也就是一个tbody标签;
2)jQuery("info").find("tr")是拿到tbody所有的tr标签;
3)jQuery("info").find("tr").each(function(i){});进行遍历所有的tr标签
4)jQuery(this).find("th:first").find("input").prop("checked")==true
5)拿到里面的id并把它们拼接成一个用","进行分割的字符串,并使用ajax的方式给后端发送一个HTTP请求;
后端代码:
@RequestMapping("/deleteAll") @Transactional public int deleteAll(String listInteger,HttpServletRequest req){ //1.先进行判断前端传递的参数是否为空 if(listInteger==null||listInteger.equals("")){ System.out.println("当前你删除的是自己,不能进行删除"); return -1; } String nums[]=listInteger.split(","); List<Integer> list=new ArrayList<>(); //2.再进行判断当前用户删除的是否是自己的信息,并把一个字符串转化成一个整数,最终把一个字符串数组转化成包含若干userID的list数组 HttpSession httpSession=req.getSession(false); UserInfo userInfo= (UserInfo) httpSession.getAttribute("user"); for(String num:nums) { if (Integer.parseInt(num)==userInfo.getUserID()){ System.out.println("当前你删除的字段中包含自己删除失败"); return -1; } list.add(Integer.parseInt(num)); } //3.进行批量删除操作 return userService.deleteAll(list); }
//7.删除多个用户 @RequestMapping("/deleteUsers") @ResponseBody public boolean deleteUsers(String listInteger,HttpServletRequest req){ //1.进行参数校验 if(listInteger==null||listInteger.equals("")){ return false; } //2.进行字符串拆分 List<Integer> list=new ArrayList<>(); String[] result=listInteger.split(","); if(result==null||result.length()==null){ reurn false; } for(String str:result) { int data = Integer.parseInt(str); System.out.println(data); list.add(data); } //3.判断当前删除的用户是否是当前登录的用户,不能自己删除自己 HttpSession session= req.getSession(false); User loginUser=(User)session.getAttribute("user"); for(int userID:list){ if(userID==loginUser.getUserID()){ return false; } } //4.正式进行删除操作 userMapper.deleteUsers(list); return true; }
function del(){ string=""; let checkboxs=document.querySelectorAll(".checkboxs"); for(var i=0;i<checkboxs.length;i++){ if(checkboxs[i].checked){ string=string+","+checkboxs[i].getAttribute("id"); } } string=string.substring(1,string.length); $.ajax({ type:"GET", url:"/Java100/deleteUsers", contentType:"application/x-www-form-urlencoded", data:{"listInteger":string}, success:function(data,status){ if(data.state==1&&data.data==true){ alert("删除所有用户成功"); location.href="list.html"; }else{ alert("删除失败"); } } }); }
之前使用vue进行拼接的时候,给每一个checkbox框加上一个class属性,全部获取,查看他们的选中状态;
13) 实现分页查询:
<a href="javascript:firstAge()">点击我发送请求</a> <script> function firstAge(){ alert("生命在于运动"); } </script> //当我们进行点击a标签的时候,就会自动跳转到执行这个函数
对于分页查询来说:
select * from userInfo limit 2 offset 2
假设现在是第2页(pindex),每一页展示2条数据(psize)
第一页:显示条数:select * from userInfo limit 2(psize) offset 0
第二页:显示条数:select * from userInfo limit 2(psize) offset 2
那么offset里面的值就是(pindex-1)*psize----->(页码-1)*每一页展示多少条
1)后端返回分页查询的结果也就是用户信息
2)后端还要返回查询用到了多少行数(一共有多少条数据)
前端给后端传递的参数:
当前页数+展示条数+查询的用户名+查询的邮箱+查询的地址信息
后端用于进行测试的代码:
//127.0.0.1:8080/Java100?pindex=1&psize=3&userName=XXX&address=XXX&email=XXX //这是针对前段只传递如上所示的代码才会生效的进行 @RequestMapping("/GetAllByAge") public HashMap<String,Object> GetListByPage(Integer pindex,String userName,String email,String address,Integer psize){ HashMap<String,Object> result=new HashMap<>(); //1.校验参数的合法性,校验传递的页码和一页中显示的条数 if(pindex==null||psize==null){ result.put("message","前段传递的页码和一页中显示的条数为空"); return result; } //2.校验参数内容的合法性 if(pindex<1||psize<=0) { result.put("message","前段传递的一页中显示的条数和页码出现参数错误"); return result; } //3.计算offset的值 int offset=(pindex-1)*psize; int limit=psize; //4.得到所有的用户信息 List<UserInfo> allList=userService.SelectUserInfoAllByAge( userName,email,address,limit,offset); //5.得到当前查询的总条数 int UserInfoSize=userService.SelectAgeCount(userName,address,email); result.put("data1",allList); result.put("data2",UserInfoSize); //6返回结果给前端 return result; } }
进行查找获取当前行数的代码:
<select id="SelectAgeCount" resultType="java.lang.Integer"> select count(*) from userInfo where <trim suffixOverrides=","> <if test="userName!=null"> userName=#{userName} </if> <if test="address!=null"> and address=#{address} </if> <if test="email!=null"> and email=#{email} </if> </trim> </select>
进行分页查找的XML代码:
<select id="SelectUserInfoAllByAge" resultType="com.example.demo.Model.UserInfo"> select * from userInfo where <trim suffixOverrides=","> <if test="userName!=null"> userName=#{userName} </if> <if test="address!=null"> and address=#{address} </if> <if test="email!=null"> and email=#{email} </if> </trim> limit #{limit} offset #{offset} </select>
实现分页查询后端:
约定前后端交互的接口:
前端: POST /GetAllUsers Http/1.1 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 username=&address=&email=&psize=3&pindex=1 后端: { "data": { "count":1,//代表根据条件查询的总条数 "resultlist"://代表着当前页面所展示的用户信息 [{ "userID":1,"username":"小淘气","loginname":"zhangsan","password":"12503487","sex":"男","age":25,"address":"中国","qq":"25","email":"139.com","isadmin":1,"createtime":"2023-04-03T11:37:03.000+00:00","updatetime":"2023-04-03T11:37:03.000+00:00"}]}, "state":1, "status":200 }
1)前端传递参数分析:页码 页数 姓名 籍贯 邮箱,其中姓名支持模糊查询
2)后端返回的数据:用户的信息,还有信息总条数
3)至于分页的页数直接就在前端计算即可,用后端返回的信息总条数除以每一页显示的条数就等于一共要显示多少页
一)先实现前端基本的分页查询功能,基本的url是:
127.0.0.1:8080/list.html?pindex=XX&username=XX&password=XX&address=XX
<script> //实现分页查询前端 var username=""; var address=""; var email=""; //代表总页码 var totalpage=3; //代表当前页码 var psize=1; //初始化页面给三个属性赋值:获取到url中的三个参数 var queryString=location.search; queryString=queryString.substring(1,queryString.length); var strings=queryString.split("&"); for(var i=0;i<strings.length;i++){ array=strings[i].split("="); if(array[0]=="username"){ username=array[1]; } if(array[0]=="address"){ address=array[1]; } if(array[0]=="email"){ email=array[1]; } if(array[0]=="psize"){ psize=array[1]; } } psize=parseInt(psize); function firstPage(){ psize=1; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?psize="+1+"&username="+username+"&address="+address+"&email="+email; } function lastPage(){ psize=totalpage; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?psize="+totalpage+"&username="+username+"&address="+address+"&email="+email; } function beforePage(){ if(psize>1){ psize=psize-1; location.href="list.html?psize="+psize+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是第一页"); return false; } } function nextPage(){ if(psize<totalpage){ psize=psize+1; location.href="list.html?psize="+psize+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是最后一页"); } } </script> </body>
二)原来是页面一进行加载list.html的时候就去给后端发送HTTP请求来获取页面上的所有数据,然后整个页面会把所有数据都渲染到前端页面上;
三)现在我们要针对前端进行修改,能够像后端发送一个基本的HTTP请求:
<script> //获取用户列表数据 var app=new Vue({ el:"#info", data:{ userinfos:[] }, methods:{ getAll(){ $.ajax({ type:"POST", url:"Java100/getAllUsers", data:{ "username":username, "address":address, "email":email, "psize":psize, "pindex":pindex, }, context:this, success:function(data,status){ this.userinfos=data.data; } }); } } }); //删除多条用户的JS function del(){ string=""; let checkboxs=document.querySelectorAll(".checkboxs"); for(var i=0;i<checkboxs.length;i++){ if(checkboxs[i].checked){ string=string+","+checkboxs[i].getAttribute("id"); } } string=string.substring(1,string.length); $.ajax({ type:"GET", url:"/Java100/deleteUsers", contentType:"application/x-www-form-urlencoded", data:{"listInteger":string}, success:function(data,status){ if(data.state==1&&data.data==true){ alert("删除所有用户成功"); location.href="list.html"; }else{ alert("删除失败"); } } }); } </script> <script> //实现分页查询前端 var username=""; var address=""; var email=""; //代表总页码 var totalpage=3; //代表当前页码 var pindex=1; //代表当前页面的总条数 var totalCount=0; //代表每一页显示的条数 var psize=3; //初始化页面给三个属性赋值:获取到url中的三个参数 var queryString=location.search; queryString=queryString.substring(1,queryString.length); var strings=queryString.split("&"); for(var i=0;i<strings.length;i++){ array=strings[i].split("="); if(array[0]=="username"){ username=array[1]; } if(array[0]=="address"){ address=array[1]; } if(array[0]=="email"){ email=array[1]; } if(array[0]=="pindex"){ pindex=array[1]; } } //先进行像后端发送HTTP请求,来请求当前页面要进行展示的数据 app.getAll(); pindex=parseInt(pindex); //当前端获取到这三个参数的时候,就立即向后端发送HTTP请求来获取所有数据 function firstPage(){ pindex=1; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?pindex="+1+"&username="+username+"&address="+address+"&email="+email; } function lastPage(){ pindex=totalpage; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?pindex="+totalpage+"&username="+username+"&address="+address+"&email="+email; } function beforePage(){ if(pindex>1){ pindex=pindex-1; location.href="list.html?pindex="+pindex+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是第一页"); return false; } } function nextPage(){ if(pindex<totalpage){ pindex=pindex+1; location.href="list.html?pindex="+pindex+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是最后一页"); } } </script>
<script> //实现分页查询前端 var username=""; var address=""; var email=""; //代表总页码 var totalpage=""; //代表当前页码 var pindex=1; //代表当前页面的总条数 var totalCount=0; //代表每一页显示的条数 var psize=3; //初始化页面给三个属性赋值:获取到url中的三个参数 var queryString=location.search; queryString=queryString.substring(1,queryString.length); var strings=queryString.split("&"); for(var i=0;i<strings.length;i++){ array=strings[i].split("="); if(array[0]=="username"){ username=array[1]; } if(array[0]=="address"){ address=array[1]; } if(array[0]=="email"){ email=array[1]; } if(array[0]=="pindex"){ pindex=array[1]; } } //先进行像后端发送HTTP请求,来请求当前页面要进行展示的数据 app.getAll(); pindex=parseInt(pindex); //当前端获取到这三个参数的时候,就立即向后端发送HTTP请求来获取所有数据 //点击第一页触发的JS function firstPage(){ pindex=1; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?pindex="+1+"&username="+username+"&address="+address+"&email="+email; } //点击最后一页触发的JS function lastPage(){ pindex=totalpage; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?pindex="+totalpage+"&username="+username+"&address="+address+"&email="+email; } //点击上一页触发的JS function beforePage(){ if(pindex>1){ pindex=pindex-1; location.href="list.html?pindex="+pindex+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是第一页"); return false; } } //点击下一页触发的JS function nextPage(){ if(pindex<totalpage){ pindex=pindex+1; location.href="list.html?pindex="+pindex+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是最后一页"); } } </script>
四)能够获取用户名,籍贯,以及地址栏对应的信息以及显示总页数,编写查询事件;
<script> //获取用户列表数据 var app=new Vue({ el:"#info", data:{ userinfos:[] }, methods:{ getAll(){ $.ajax({ type:"POST", url:"Java100/getAllUsers", contentType:"application/x-www-form-urlencoded;charset=UTF-8", data:{ "username":username, "address":address, "email":email, "psize":psize, "pindex":pindex, }, context:this, success:function(data,status){ if(data.data.count!=0&&data.data.resultlist!=""){ this.userinfos=data.data.resultlist; totalCount=data.data.count; totalpage=Math.ceil(parseInt(totalCount)/psize); let span=document.querySelector(".data"); span.innerHTML="共"+totalCount+"条记录,共"+totalpage+"页"; }else if(data.data.count==0||data.data.resultlist==""){ alert("未查询出用户数据"); } } }); } } }); //删除多条用户的JS function del(){ string=""; let checkboxs=document.querySelectorAll(".checkboxs"); for(var i=0;i<checkboxs.length;i++){ if(checkboxs[i].checked){ string=string+","+checkboxs[i].getAttribute("id"); } } string=string.substring(1,string.length); $.ajax({ type:"GET", url:"/Java100/deleteUsers", contentType:"application/x-www-form-urlencoded", data:{"listInteger":string}, success:function(data,status){ if(data.state==1&&data.data==true){ alert("删除所有用户成功"); location.href="list.html"; }else{ alert("删除失败"); } } }); } </script> <script> //实现分页查询前端 var username=""; var address=""; var email=""; //代表总页码 var totalpage=""; //代表当前页码 var pindex=1; //代表当前页面的总条数 var totalCount=0; //代表每一页显示的条数 var psize=3; //初始化页面给三个属性赋值:获取到url中的三个参数 var queryString=location.search; queryString=queryString.substring(1,queryString.length); var strings=queryString.split("&"); for(var i=0;i<strings.length;i++){ array=strings[i].split("="); if(array[0]=="username"){ username=array[1]; } if(array[0]=="address"){ address=array[1]; } if(array[0]=="email"){ email=array[1]; } if(array[0]=="pindex"){ pindex=array[1]; } } //先进行像后端发送HTTP请求,来请求当前页面要进行展示的数据 app.getAll(); pindex=parseInt(pindex); //当前端获取到这三个参数的时候,就立即向后端发送HTTP请求来获取所有数据 //点击第一页触发的JS function firstPage(){ pindex=1; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?pindex="+1+"&username="+username+"&address="+address+"&email="+email; } //点击最后一页触发的JS function lastPage(){ pindex=totalpage; //如果是没有联合查询,那么没有传递这三个参数,直接展示所有即可,但是如果指定查询条件,那么必须传递这三个参数 location.href="list.html?pindex="+totalpage+"&username="+username+"&address="+address+"&email="+email; } //点击上一页触发的JS function beforePage(){ if(pindex>1){ pindex=pindex-1; location.href="list.html?pindex="+pindex+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是第一页"); return false; } } //点击下一页触发的JS function nextPage(){ if(pindex<totalpage){ pindex=pindex+1; location.href="list.html?pindex="+pindex+"&username="+username+"&address="+address+"&email="+email; }else{ alert("已经是最后一页"); } } //点击查询按钮 function onSearch(){ //1.先进行获取到三个输入框里面的内容 var username_input=jQuery.trim(jQuery("#ipt_name").val()); var address_input=jQuery.trim(jQuery("#ipt_address").val()); var email_input=jQuery.trim(jQuery("#ipt_email").val()); location.href="list.html?pindex="+1+"&username="+username_input+"&address="+address_input+"&email="+email_input; } </script>
分页查询的后端代码:
@RequestMapping("/GetAllByAge") public HashMap<String,Object> GetListByPage(Integer pindex,String userName,String email,String address,Integer psize){ HashMap<String,Object> result=new HashMap<>(); //1.假设当前没有传递任何参数,我们就手动给他设置参数,我们这样处理的目的就是当我们首次访问list.html可以 if(pindex==null||pindex<1){ pindex=1; } if(psize==null||psize<0){ psize=2; } //注意,下面的这三步不可以进行删除省略,因为如果前端传递的username,emial或者address是空,那么最终生成的SQL语句也会进行查询 if(userName==null||userName.equals("")) { userName=null; } if(address==null||address.equals("")){ address=null; } if(email==null||email.equals("")){ email=null; } //3.计算offset的值 int offset=(pindex-1)*psize; int limit=psize; //4.得到所有的用户信息 List<UserInfo> allList=userService.SelectUserInfoAllByAge( userName,email,address,limit,offset); //5.得到当前查询信息的总条数 int UserInfoSize=userService.SelectAgeCount(userName,address,email); result.put("data1",allList); result.put("data2",UserInfoSize); //6返回结果给前端 return result; } }
获取到信息的总条数:虽然返回类型是整数,但是不要写成
1)parameterType=""
2)resultMap=""具体的实体类的名字,不然程序会报错
<select id="getCountUser" resultType="java.lang.Integer"> select count(*) from user <where> <if test="username!=null"> and username=#{username} </if> <if test="address!=null"> and address=#{address} </if> <if test="email!=null"> and email=#{email} </if> </where> </select>
获取到所有的用户信息:
<select id="getCountUser" resultType="java.lang.Integer" > select count(*) from user <where> <if test="username!=null"> and username=#{username} </if> <if test="address!=null"> and address=#{address} </if> <if test="email!=null"> and email=#{email} </if> </where> </select>
14)实现密码加密:
注册:
加密:盐值+@+转换算法(盐值(通常使用随机数)+加密的数据)===加密之后的密码
登录:解密
1)先获取到随机盐值,通过字符串拆分的方式也就是split方法来获取到@之前的字符串,也就是之前加密过的随机盐值;
2)在获取到@后面的字符串,记录一下是SaltPassword
2)通过第一步的得到的盐值+用户登录的密码在生成一次加密密码,如果和SaltPassword相同,说明登陆成功,否则登陆失败
1)导入加密算法的框架:
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.0</version> </dependency>
2)下面是加密的和解密的操作以及测试用例
public class PassWordUtil { public static String encrypt(String password){ //1.先得到盐值 String salt= IdUtil.simpleUUID(); System.out.println(salt); //2.进行加密 String finalPassWord= SecureUtil.md5(salt+password); System.out.println(finalPassWord); return salt+"@"+finalPassWord; } public static boolean decrypt(String password,String finalPassword){ //1.先进性参数校验 if(finalPassword==null||finalPassword.equals("")||finalPassword.length()!=65||password==null||password.equals("")){ return false; } //2.进行解密 String[] strings=finalPassword.split("@"); String salt=strings[0]; String NewPassword=SecureUtil.md5(salt+password); if(NewPassword.equals(strings[1])){ return true; } return false; } public static void main(String[] args) { String before="123456"; String password= PassWordUtil.encrypt(before); System.out.println(PassWordUtil.decrypt(before, password)); String strx="1234567"; System.out.println(PassWordUtil.decrypt(password,strx)); } }
3)应该在总代码汇总修改的部分
1)在登录过程中,要针对用户传递过的密码1,再从数据库中根据用户名查询密码2,加密之后的密码,在进行加密之后的密码2里面获取到盐值,根据盐值+密码1生成加密之后的密码3,在进行对比密码2和密码3,如果相同,那么登陆成功;
2)在进行添加用户的时候,后端获取到密码进行加密,再存入数据库里面;
3)再进行修改用户的时候,会进行判断前端传递的密码是否为空,如果不为空,那么直接进行加密密码;
分页查询前端代码:
1)获取请求中URL的参数
2)以及各种点击事件
3)以及我们进行点击查询之后所显示的所有数据记录
function oncli(){ //点击查询之后,我们会将里面的内容全部取出来,赋值给前端里面的每一个全局变量里面 var userNameHHH=jQuery.trim(jQuery("#ipt_name").val()); var addressHHH=jQuery.trim(jQuery("ipt_address").val()); var emailHHH=jQuery.trim(jQuery("#ipt_email").val()); userInfo_address=addressHHH; userInfo_email=emailHHH; userInfo_name=userNameHHH; app.GetAll(); } //下面是查询的字段,必须定义为全局变量,否则前端页面一但进行刷新就没了 var userInfo_name=""; var userInfo_address=""; var userInfo_email=""; //下面是总页数 var totalsize=""; //下面表示总条数 var totallog=""; //下面是当前页码 var pindex=1; //下面表示一页先两条条数据 var psize=2; function getParamter(){ //下面获取url的参数 var queryString=location.search; var list=[]; var queryString=queryString.substr(1,queryString.length); //按照&来进行分割 var array=queryString.split("&"); for(let messages of array){ var message=messages.split("="); if(message[0]=="userName"){ userInfo_name=message[1]; } if(message[0]=="address"){ userInfo_address=message[1]; } if(message[0]=="email"){ userInfo_email=message[1]; } if(message[0]=="pindex"){ pindex=parseInt(message[1]); } } app.GetAll(); } getParamter(); console.log(userInfo_name); console.log(userInfo_email); console.log(userInfo_address); console.log(totalsize); console.log(pindex); //分页查询 //1.当我们进行点击首页之后 function firstPage(){ location.href="list.html?"+"pindex=1&"+"&userName="+userInfo_name+"&address="+userInfo_address+"&email="+userInfo_email; } //2.当我们进行点击末页的话 function lastPage(){ location.href="list.html?pindex="+totalsize+"&userName="+userInfo_name+"&address="+userInfo_address+"&email="+userInfo_email; } //3.点击上一页 function beforePage(){ //先进行判断 if(pindex-1>0){ pindex=pindex-1; location.href="list.html?pindex="+pindex+"&userName="+userInfo_name+"&address="+userInfo_address+"&email="+userInfo_email; }else{ alert("当前已经是第一页了"); } } //4.点击下一页 function nextPage(){ if(pindex+1<=totalsize){ pindex=pindex+1; location.href="list.html?pindex="+pindex+"&userName="+userInfo_name+"&address="+userInfo_address+"&email="+userInfo_email; }else {alert("当前已经是最后一页了");} }
var app=new Vue({ el:"#info", data(){ return{ userInfos:[] } }, methods:{ GetAll(){ $.ajax({ type:"GET", url:"Java100/GetAllByAge", context:this, data:{ "pindex":pindex, "userName":userInfo_name, "email":userInfo_email, "address":userInfo_address, "psize":psize, }, success:function(data,status){ // console.log(typeof data.data); // console.log(data,status); app.userInfos= data.data.data1; //先进行计算总条数 var totallog=parseInt(data.data.data2); //再进行计算总页数 totalsize=Math.ceil(totallog/psize); // console.log(app.userInfos); //进行设置总条数和总页数 jQuery("#pageInfo").html("共"+totallog+"条记录"+"一共"+totalsize+"页") } }); } } });