The SQL statement that needs to be executed when the user changes the password is roughly:
UPDATE t_user SET password=?, modified_user=?, modified_time=? WHERE uid=?
Before changing the password, you should also check whether the user data exists, check whether the user data is marked as "deleted", and check the original password Whether it is correct or not, these checks can be assisted by querying user data:
SELECT * FROM t_user WHERE uid=?
Add updatePasswordByUid(Integer uid,String password,String modifiedUser,Date modifiedTime in the UserMapper interface ) abstract method.
When using annotations to simplify xml configuration, the @Param annotation is used to name the parameters. After the parameters are named, the parameter values can be obtained based on the names, and the parameters can be correctly passed into the sql statement. The parameter name in the @Param("parameter name") annotation needs to be consistent with the parameter name of #{parameter name} in the sql statement.
/** * 根据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. Configure the mapping of updatePasswordByUid() and findByUid() abstract methods in UserMapper.xml.
<!-- 根据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. Write and execute unit tests in UserMapperTests.
@Test public 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); } @Test public void findByUid() { Integer uid = 7; User result = userMapper.findByUid(uid); System.out.println(result); }
Before changing the password, you must first check whether the user data exists and is not marked as "deleted" ". A UserNotFoundException should be thrown if the check fails.
2. When the user changes the password, the modification may fail because the original password entered is incorrect, and a PasswordNotMatchException exception should be thrown.
If the number of affected rows is different from the expected value when changing the password, an UpdateException should be thrown.
4. Create the com.cy.store.service.ex.UpdateException exception class, which inherits from the ServiceException class.
/** 更新数据的异常 */ public class UpdateException extends ServiceException { // Override Methods... }
Add the changePassword(Integer uid, String username, String oldPassword, String newPassword) abstract method in IUserService.
/** * 修改密码 * @param uid 当前登录的用户id * @param username 用户名 * @param oldPassword 原密码 * @param newPassword 新密码 */ public void changePassword(Integer uid, String username, String oldPassword, String newPassword);
1. Implement the changePassword() abstract method in the UserServiceImpl class.
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. The specific code of the changePassword() method.
The equals and contentEquals methods in String can be used to compare whether the contents of String objects are the same.
@Override public 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. Write and execute unit tests in UserServiceTests.
@Test public 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()); } }
A new UpdateException exception is thrown in the business of user changing password, which needs to be in the BaseController class for processing.
@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; }
Design the request submitted by the user and design the response.
Request path:/users/change_password
Request parameters: String oldPassword, String newPassword, HttpSession session
Request type: POST
Response result: JsonResult903bf37051cf83cbd9686768ac0189ae
1. Add the changePassword(String oldPassword, String newPassword, HttpSession session) method for processing requests in the UserController class.
@RequestMapping("change_password") public JsonResult<Void> changePassword(String oldPassword, String newPassword, HttpSession session) { // 调用session.getAttribute("")获取uid和username // 调用业务对象执行修改密码 // 返回成功 return null; }
2. Implement the code to change the password method in the UserController controller.
@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. Log in first to start the project, and then visit http://localhost:8080/users/change_password?oldPassword=xx&newPassword=xx for testing.
1. At the end of the body tag in the password.html page, add a script tag for writing JavaScript programs.
<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. Log in first to start the project, then visit the http://localhost:8080/web/password.html page and change the password.
Question: If the data cannot be transferred to the background normally, restart the system and IDEA development tools, and then you can change the password after logging in.
3. Problem: When operating the front-end page, the user enters the password change page and stays on the current page for a long time without performing any operations, which will cause the login information to expire. When you click the modify button at this time, a request will still be sent to /users/change_password and will be redirected to the login page by the interceptor. Since the entire process is handled asynchronously by the $.ajax() function, the redirection is also completed by an asynchronous task. If there is no performance on the page, "Nothing happens when clicking the button after the user's login information times out" will appear. question.
Solution: You can add the configuration of the error attribute in $.ajax() of the password.html page. The value of this attribute is a callback function. This function will be called when the server returns a status code that does not respond normally, such as 302, 400, 404, 405, 500, etc.
error: function (xhr) { alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status); location.href = "login.html"; }
1. Execute and modify the user The SQL statement of personal data is roughly:
UPDATE t_user SET phone=?, email=?, gender=?, modified_user=?, modified_time=? WHERE uid=?
Before the user opens the page to modify the data, the information of the currently logged-in user should be displayed on the page to facilitate verification before performing the data modification operation. User information can be displayed through:
SELECT * FROM t_user WHERE uid=?
Description:
1. This query function has been implemented and does not need to be developed again;
在进行用户资料修改前,还需要进行检查,判断用户数据是否存在、是否被标记为“已删除”,以上查询也可以用来实现这一操作。
在UserMapper接口中添加updateInfoByUid(User user)方法。
/** * 根据uid更新用户资料 * @param user 封装了用户id和新个人资料的对象 * @return 受影响的行数 */ Integer updateInfoByUid(User user);
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中编写并执行单元测试。
@Test public 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); }
1.关于用户修改个人资料是由两个功能组成的。
打开页面时显示当前登录的用户的信息;
点击修改按钮时更新用户的信息。
2.关于打开页面时显示当前登录的用户的信息,可能会因为用户数据不存在、用户被标记为“已删除”而无法正确的显示页面,则抛出UserNotFoundException异常。
3.关于点击修改按钮时更新用户的信息,在执行修改资料之前仍需再次检查用户数据是否存在、用户是否被标记为“已删除”,则可能抛出UserNotFoundException异常。在修改资料时,可能会发生UpdateException异常。
在IUserService接口中添加两个抽象方法,分别对应以上两个功能。
/** * 获取当前登录的用户的信息 * @param uid 当前登录的用户的id * @return 当前登录的用户的信息 */ User getByUid(Integer uid); /** * 修改用户资料 * @param uid 当前登录的用户的id * @param username 当前登录的用户名 * @param user 用户的新的数据 */ void changeInfo(Integer uid, String username, User user);
1.在UserServiceImpl实现类中实现getByUid(Integer uid)和changeInfo(Integer uid, String username, User user)以上两个抽象方法。
@Override public User getByUid(Integer uid) { // 调用userMapper的findByUid()方法,根据参数uid查询用户数据 // 判断查询结果是否为null // 是:抛出UserNotFoundException异常 // 判断查询结果中的isDelete是否为1 // 是:抛出UserNotFoundException异常 // 创建新的User对象 // 将以上查询结果中的username/phone/email/gender封装到新User对象中 // 返回新的User对象 return null; } @Override public 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)方法的具体代码实现。
@Override public 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; } @Override public 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类中进行单元测试。
@Test public 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()); } } @Test public 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()); } }
说明:无需再次开发。
1.设计用户提交显示当前登录的用户信息的请求,并设计响应的方式。
请求路径:/users/get_by_uid
请求参数:HttpSession session
请求类型:GET
响应结果:JsonResult4c8e0c17c3bd7e0081bb17cc795e1984
2.设计用户提交执行修改用户信息的请求,并设计响应的方式。
请求路径:/users/change_info
请求参数:User user, HttpSession session
请求类型:POST
响应结果:JsonResult903bf37051cf83cbd9686768ac0189ae
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进行测试。
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页面并进行用户个人资料的修改测试。
The above is the detailed content of How to modify springboot user data. For more information, please follow other related articles on the PHP Chinese website!