修改密码1 用户-修改密码-持久层1.1 规划需要执行的sql语句用户修改密码时需要执行的sql语句大致是:
update t_user set password=?, modified_user=?, modified_time=? where uid=?
在执行修改密码之前,还应检查用户数据是否存在、并检查用户数据是否被标记为“已删除”、并检查原密码是否正确,这些检查都可以通过查询用户数据来辅助完成:
select * from t_user where uid=?
1.2 接口与抽象方法在usermapper接口添加updatepasswordbyuid(integer uid,string password,string modifieduser,date modifiedtime)抽象方法。
用注解来简化xml配置时,@param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中。@param("参数名")注解中的参数名需要和sql语句中的#{参数名}的参数名保持一致。
/** * 根据uid更新用户的密码 * @param uid 用户的id * @param password 新密码 * @param modifieduser 最后修改执行人 * @param modifiedtime 最后修改时间 * @return 受影响的行数 */integer updatepasswordbyuid( @param("uid") integer uid, @param("password") string password, @param("modifieduser") string modifieduser, @param("modifiedtime") date modifiedtime);/** * 根据用户id查询用户数据 * @param uid 用户id * @return 匹配的用户数据,如果没有匹配的用户数据,则返回null */user findbyuid(integer uid);
1.3 配置sql映射1.在usermapper.xml中配置updatepasswordbyuid()、findbyuid()抽象方法的映射。
<!-- 根据uid更新用户的密码: integer updatepasswordbyuid( @param("uid") integer uid, @param("password") string password, @param("modifieduser") string modifieduser, @param("modifiedtime") date modifiedtime) --><update id="updatepasswordbyuid"> update t_user set password = #{password}, modified_user = #{modifieduser}, modified_time = #{modifiedtime} where uid = #{uid}</update><!-- 根据用户id查询用户数据:user findbyuid(integer uid) --><select id="findbyuid" resultmap="userentitymap"> select * from t_user where uid = #{uid}</select>
2.在usermappertests中编写并执行单元测试。
@testpublic void updatepasswordbyuid() { integer uid = 7; string password = "123456"; string modifieduser = "超级管理员"; date modifiedtime = new date(); integer rows = usermapper.updatepasswordbyuid(uid, password, modifieduser, modifiedtime); system.out.println("rows=" + rows);}@testpublic void findbyuid() { integer uid = 7; user result = usermapper.findbyuid(uid); system.out.println(result);}
2 用户-修改密码-业务层2.1 规划异常在修改密码之前,必须先检查用户数据是否存在并且未被标记为“已删除”。应该抛出usernotfoundexception异常,如果检查未通过。
2.用户修改密码时,可能会因为输入的原密码错误导致修改失败,则应抛出passwordnotmatchexception异常。
如果修改密码时,受影响行数与预期值不同,则应该抛出updateexception异常。
4.创建com.cy.store.service.ex.updateexception异常类,继承自serviceexception类。
/** 更新数据的异常 */public class updateexception extends serviceexception { // override methods...}
2.2 接口与抽象方法在iuserservice中添加changepassword(integer uid, string username, string oldpassword, string newpassword)抽象方法。
/** * 修改密码 * @param uid 当前登录的用户id * @param username 用户名 * @param oldpassword 原密码 * @param newpassword 新密码 */public void changepassword(integer uid, string username, string oldpassword, string newpassword);
2.3 实现抽象方法1.在userserviceimpl类中实现changepassword()抽象方法。
public void changepassword(integer uid, string username, string oldpassword, string newpassword) { // 调用usermapper的findbyuid()方法,根据参数uid查询用户数据 // 检查查询结果是否为null // 是:抛出usernotfoundexception异常 // 检查查询结果中的isdelete是否为1 // 是:抛出usernotfoundexception异常 // 从查询结果中取出盐值 // 将参数oldpassword结合盐值加密,得到oldmd5password // 判断查询结果中的password与oldmd5password是否不一致 // 是:抛出passwordnotmatchexception异常 // 将参数newpassword结合盐值加密,得到newmd5password // 创建当前时间对象 // 调用usermapper的updatepasswordbyuid()更新密码,并获取返回值 // 判断以上返回的受影响行数是否不为1 // 是:抛了updateexception异常}
2.changepassword()方法的具体代码。
string中的equals与contentequals方法,都可以用来比较string对象内容是否相同。
@overridepublic void changepassword(integer uid, string username, string oldpassword, string newpassword) { // 调用usermapper的findbyuid()方法,根据参数uid查询用户数据 user result = usermapper.findbyuid(uid); // 检查查询结果是否为null if (result == null) { // 是:抛出usernotfoundexception异常 throw new usernotfoundexception("用户数据不存在"); } // 检查查询结果中的isdelete是否为1 if (result.getisdelete().equals(1)) { // 是:抛出usernotfoundexception异常 throw new usernotfoundexception("用户数据不存在"); } // 从查询结果中取出盐值 string salt = result.getsalt(); // 将参数oldpassword结合盐值加密,得到oldmd5password string oldmd5password = getmd5password(oldpassword, salt); // 判断查询结果中的password与oldmd5password是否不一致 if (!result.getpassword().contentequals(oldmd5password)) { // 是:抛出passwordnotmatchexception异常 throw new passwordnotmatchexception("原密码错误"); } // 将参数newpassword结合盐值加密,得到newmd5password string newmd5password = getmd5password(newpassword, salt); // 创建当前时间对象 date now = new date(); // 调用usermapper的updatepasswordbyuid()更新密码,并获取返回值 integer rows = usermapper.updatepasswordbyuid(uid, newmd5password, username, now); // 判断以上返回的受影响行数是否不为1 if (rows != 1) { // 是:抛出updateexception异常 throw new updateexception("更新用户数据时出现未知错误,请联系系统管理员"); }}
3.在userservicetests中编写并执行单元测试。
@testpublic void changepassword() { try { integer uid = 5; string username = "lower"; string oldpassword = "123456"; string newpassword = "888888"; userservice.changepassword(uid, username, oldpassword, newpassword); system.out.println("密码修改成功!"); } catch (serviceexception e) { system.out.println("密码修改失败!" + e.getclass().getsimplename()); system.out.println(e.getmessage()); }}
3 用户-修改密码-控制器3.1 处理异常在用户修改密码的业务中抛出了新的updateexception异常,需要在basecontroller类中进行处理。
@exceptionhandler(serviceexception.class)public jsonresult<void> handleexception(throwable e) { jsonresult<void> result = new jsonresult<void>(e); if (e instanceof usernameduplicateexception) { result.setstate(4000); } else if (e instanceof usernotfoundexception) { result.setstate(4001); } else if (e instanceof passwordnotmatchexception) { result.setstate(4002); } else if (e instanceof insertexception) { result.setstate(5000); } else if (e instanceof updateexception) { result.setstate(5001); } return result;}
3.2 设计请求设计用户提交的请求,并设计响应的方式。
请求路径:/users/change_password
请求参数:string oldpassword, string newpassword, httpsession session
请求类型:post
响应结果:jsonresult<void>
3.3 处理请求1.在usercontroller类中添加处理请求的changepassword(string oldpassword, string newpassword, httpsession session)方法。
@requestmapping("change_password")public jsonresult<void> changepassword(string oldpassword, string newpassword, httpsession session) { // 调用session.getattribute("")获取uid和username // 调用业务对象执行修改密码 // 返回成功 return null;}
2.实现usercontroller控制器中的修改密码方法的代码。
@requestmapping("change_password")public jsonresult<void> changepassword(string oldpassword, string newpassword, httpsession session) { // 调用session.getattribute("")获取uid和username integer uid = getuidfromsession(session); string username = getusernamefromsession(session); // 调用业务对象执行修改密码 iuserservice.changepassword(uid, username, oldpassword, newpassword); // 返回成功 return new jsonresult<void>(ok);}
3.启动项目先登录,再访问http://localhost:8080/users/change_password?oldpassword=xx&newpassword=xx进行测试。
4 用户-修改密码-前端页面1.在password.html页面中body标签内部的最后,添加script标签用于编写javascript程序。
<script type="text/javascript"> $("#btn-change-password").click(function() { $.ajax({ url: "/users/change_password", type: "post", data: $("#form-change-password").serialize(), datatype: "json", success: function(json) { if (json.state == 200) { alert("修改成功!"); } else { alert("修改失败!" + json.message); } } }); });</script>
2.启动项目先登录,再访问http://localhost:8080/web/password.html页面并进行修改密码。
问题:如果无法正常将数据传递给后台,重启动系统和idea开发工具,登陆后便可修改密码。
3.问题:在操作前端页面时用户进入修改密码页面,长时间停留在当前页面未进行任何操作,将导致登录信息过期。此时点击修改按钮时,仍会向/users/change_password发送请求,会被拦截器重定向到登录页面。由于整个过程是由$.ajax()函数采用异步的方式处理的,所以重定向也是由异步任务完成的,在页面中没有任何表现就会出现“用户登录信息超时后点击按钮没有任何反应”的问题。
解决方案:可以在password.html页面的$.ajax()中补充error属性的配置,该属性的值是一个回调函数。该函数将被调用,当服务器返回未正常响应的状态码,比如302、400、404、405、500等等。
error: function (xhr) { alert("您的登录信息已经过期,请重新登录!http响应码:" + xhr.status); location.href = "login.html";}
个人资料1 用户-个人资料-持久层1.1 规划需要执行的sql语句1.执行修改用户个人资料的sql语句大致是:
update t_user set phone=?, email=?, gender=?, modified_user=?, modified_time=? where uid=?
在用户打开修改资料的页面之前,应当在页面上显示当前登录用户的信息,以便执行资料修改操作前进行核对。显示用户资料可以通过:
select * from t_user where uid=?
说明:
1.该查询功能已经实现,无需再次开发;
在进行用户资料修改前,还需要进行检查,判断用户数据是否存在、是否被标记为“已删除”,以上查询也可以用来实现这一操作。
1.2 接口与抽象方法在usermapper接口中添加updateinfobyuid(user user)方法。
/** * 根据uid更新用户资料 * @param user 封装了用户id和新个人资料的对象 * @return 受影响的行数 */integer updateinfobyuid(user user);
1.3 配置sql映射1.在usermapper.xml中配置integer updateinfobyuid(user user)抽象方法的映射。
<!-- 根据uid更新用户个人资料:integer updateinfobyuid(user user) --><update id="updateinfobyuid"> update t_user set <if test="phone != null">phone = #{phone},</if> <if test="email != null">email = #{email},</if> <if test="gender != null">gender = #{gender},</if> modified_user = #{modifieduser}, modified_time = #{modifiedtime} where uid = #{uid}</update>
2.在usermappertests中编写并执行单元测试。
@testpublic void updateinfobyuid() { user user = new user(); user.setuid(20); user.setphone("17858802222"); user.setemail("admin@cy.com"); user.setgender(1); user.setmodifieduser("系统管理员"); user.setmodifiedtime(new date()); integer rows = usermapper.updateinfobyuid(user); system.out.println("rows=" + rows);}
2 用户-个人资料-业务层2.1 规划异常1.关于用户修改个人资料是由两个功能组成的。
打开页面时显示当前登录的用户的信息;
点击修改按钮时更新用户的信息。
2.关于打开页面时显示当前登录的用户的信息,可能会因为用户数据不存在、用户被标记为“已删除”而无法正确的显示页面,则抛出usernotfoundexception异常。
3.关于点击修改按钮时更新用户的信息,在执行修改资料之前仍需再次检查用户数据是否存在、用户是否被标记为“已删除”,则可能抛出usernotfoundexception异常。在修改资料时,可能会发生updateexception异常。
2.2 接口与抽象方法在iuserservice接口中添加两个抽象方法,分别对应以上两个功能。
/** * 获取当前登录的用户的信息 * @param uid 当前登录的用户的id * @return 当前登录的用户的信息 */user getbyuid(integer uid);/** * 修改用户资料 * @param uid 当前登录的用户的id * @param username 当前登录的用户名 * @param user 用户的新的数据 */void changeinfo(integer uid, string username, user user);
2.3 实现抽象方法1.在userserviceimpl实现类中实现getbyuid(integer uid)和changeinfo(integer uid, string username, user user)以上两个抽象方法。
@overridepublic user getbyuid(integer uid) { // 调用usermapper的findbyuid()方法,根据参数uid查询用户数据 // 判断查询结果是否为null // 是:抛出usernotfoundexception异常 // 判断查询结果中的isdelete是否为1 // 是:抛出usernotfoundexception异常 // 创建新的user对象 // 将以上查询结果中的username/phone/email/gender封装到新user对象中 // 返回新的user对象 return null;}@overridepublic void changeinfo(integer uid, string username, user user) { // 调用usermapper的findbyuid()方法,根据参数uid查询用户数据 // 判断查询结果是否为null // 是:抛出usernotfoundexception异常 // 判断查询结果中的isdelete是否为1 // 是:抛出usernotfoundexception异常 // 向参数user中补全数据:uid // 向参数user中补全数据:modifieduser(username) // 向参数user中补全数据:modifiedtime(new date()) // 调用usermapper的updateinfobyuid(user user)方法执行修改,并获取返回值 // 判断以上返回的受影响行数是否不为1 // 是:抛出updateexception异常 }
2.getbyuid(integer uid)和changeinfo(integer uid, string username, user user)方法的具体代码实现。
@overridepublic user getbyuid(integer uid) { // 调用usermapper的findbyuid()方法,根据参数uid查询用户数据 user result = usermapper.findbyuid(uid); // 判断查询结果是否为null if (result == null) { // 是:抛出usernotfoundexception异常 throw new usernotfoundexception("用户数据不存在"); } // 判断查询结果中的isdelete是否为1 if (result.getisdelete().equals(1)) { // 是:抛出usernotfoundexception异常 throw new usernotfoundexception("用户数据不存在"); } // 创建新的user对象 user user = new user(); // 将以上查询结果中的username/phone/email/gender封装到新user对象中 user.setusername(result.getusername()); user.setphone(result.getphone()); user.setemail(result.getemail()); user.setgender(result.getgender()); // 返回新的user对象 return user;}@overridepublic void changeinfo(integer uid, string username, user user) { // 调用usermapper的findbyuid()方法,根据参数uid查询用户数据 user result = usermapper.findbyuid(uid); // 判断查询结果是否为null if (result == null) { // 是:抛出usernotfoundexception异常 throw new usernotfoundexception("用户数据不存在"); } // 判断查询结果中的isdelete是否为1 if (result.getisdelete().equals(1)) { // 是:抛出usernotfoundexception异常 throw new usernotfoundexception("用户数据不存在"); } // 向参数user中补全数据:uid user.setuid(uid); // 向参数user中补全数据:modifieduser(username) user.setmodifieduser(username); // 向参数user中补全数据:modifiedtime(new date()) user.setmodifiedtime(new date()); // 调用usermapper的updateinfobyuid(user user)方法执行修改,并获取返回值 integer rows = usermapper.updateinfobyuid(user); // 判断以上返回的受影响行数是否不为1 if (rows != 1) { // 是:抛出updateexception异常 throw new updateexception("更新用户数据时出现未知错误,请联系系统管理员"); }}
3.在userservicetests类中进行单元测试。
@testpublic void getbyuid() { try { integer uid = 20; user user = iuserservice.getbyuid(uid); system.out.println(user); } catch (serviceexception e) { system.out.println(e.getclass().getsimplename()); system.out.println(e.getmessage()); }}@testpublic void changeinfo() { try { integer uid = 20; string username = "数据管理员"; user user = new user(); user.setphone("15512328888"); user.setemail("admin03@cy.cn"); user.setgender(2); iuserservice.changeinfo(uid, username, user); system.out.println("ok."); } catch (serviceexception e) { system.out.println(e.getclass().getsimplename()); system.out.println(e.getmessage()); }}
3 用户-个人资料-控制器3.1 处理异常说明:无需再次开发。
3.2 设计请求1.设计用户提交显示当前登录的用户信息的请求,并设计响应的方式。
请求路径:/users/get_by_uid
请求参数:httpsession session
请求类型:get
响应结果:jsonresult<user>
2.设计用户提交执行修改用户信息的请求,并设计响应的方式。
请求路径:/users/change_info
请求参数:user user, httpsession session
请求类型:post
响应结果:jsonresult<void>
3.3 处理请求1.处理获取用户信息请求
1.在usercontroller类中添加处理请求的getbyuid()方法,并导入org.springframework.web.bind.annotation.getmapping包。
@getmapping("get_by_uid")public jsonresult<user> getbyuid(httpsession session) { // 从httpsession对象中获取uid // 调用业务对象执行获取数据 // 响应成功和数据 return null;}
2.getbyuid(httpsession session)方法中具体代码实现为。
@getmapping("get_by_uid")public jsonresult<user> getbyuid(httpsession session) { // 从httpsession对象中获取uid integer uid = getuidfromsession(session); // 调用业务对象执行获取数据 user data = userservice.getbyuid(uid); // 响应成功和数据 return new jsonresult<user>(ok, data);}
3.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/users/get_by_uid请求进行测试。
2.处理修改用户个人信息请求
1.在usercontroller类中添加处理请求的changeinfo(user user, httpsession session)方法。
@requestmapping("change_info")public jsonresult<void> changeinfo(user user, httpsession session) { // 从httpsession对象中获取uid和username // 调用业务对象执行修改用户资料 // 响应成功 return null;}
2.changeinfo(user user, httpsession session)方法中具体代码实现为。
@requestmapping("change_info")public jsonresult<void> changeinfo(user user, httpsession session) { // 从httpsession对象中获取uid和username integer uid = getuidfromsession(session); string username = getusernamefromsession(session); // 调用业务对象执行修改用户资料 userservice.changeinfo(uid, username, user); // 响应成功 return new jsonresult<void>(ok);}
3.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/users/change_info?phone=17858800000&email=admin07@cy.com&gender=1进行测试。
4 用户-个人资料-前端页面1.在userdata.html页面中body标签内部的最后,添加script标签用于编写javascript程序。
<script type="text/javascript"> $(document).ready(function() { $.ajax({ url: "/users/get_by_uid", type: "get", datatype: "json", success: function(json) { if (json.state == 200) { console.log("username=" + json.data.username); console.log("phone=" + json.data.phone); console.log("email=" + json.data.email); console.log("gender=" + json.data.gender); $("#username").val(json.data.username); $("#phone").val(json.data.phone); $("#email").val(json.data.email); let radio = json.data.gender == 0 ? $("#gender-female") : $("#gender-male"); radio.prop("checked", "checked"); } else { alert("获取用户信息失败!" + json.message); } } }); }); $("#btn-change-info").click(function() { $.ajax({ url: "/users/change_info", type: "post", data: $("#form-change-info").serialize(), datatype: "json", success: function(json) { if (json.state == 200) { alert("修改成功!"); location.href = "login.html"; } else { alert("修改失败!" + json.message); } }, error: function(xhr) { alert("您的登录信息已经过期,请重新登录!http响应码:" + xhr.status); location.href = "login.html"; } }); });</script>
2.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/web/userdata.html页面并进行用户个人资料的修改测试。
以上就是springboot用户数据怎么修改的详细内容。