store(商城项目)Springboot+springmvc+ajax+mybatis(四)

13. 用户-修改密码-业务层

(a) 规划可能出现的异常

最终需要执行的是更新密码操作,则可能出现更新失败的问题,则应该抛出UpdateException

在执行更新之前,应该检查用户数据是否存在,如果用户数据不存在,则抛出UserNotFoundException

并且,继续检查用户数据状态是否正确,例如isDelete是否为0,否则,将抛出UserNotFoundException

在执行更新密码之前,还应该检查原密码是否正确,如果不匹配,则抛出PasswordNotMatchException

所以,需要在cn.tedu.store.service.ex包中创建UpdateException

(b) 业务接口及抽象方法

IUserService接口中添加抽象方法:

void changePassword(Integer uid, String oldPassword, String newPassword, String username);

(c) 实现抽象方法

UserServiceImpl类中实现以上抽象方法:

public void changePassword(Integer uid, String oldPassword, String newPassword, String username) {
    // 日志:输出原密码,新密码
    // 基于参数uid调用userMapper的findByUid()查询用户数据
    // 判断查询结果是否为null
    // 是:UserNotFoundException

    // 判断查询结果中的isDelete是否为1
    // 是:UserNotFoundException

    // 从查询结果中取出盐值
    // 日志:“将原密码执行加密”
    // 将参数oldPassword结合盐值执行加密,得到oldMd5Password
    // 日志:输出查询结果中的password
    // 判断oldMd5Password与查询结果中的password是否不一致
    // 是:PasswordNotMatchException

    // 日志:“将新密码执行加密”
    // 将参数newPassword结合盐值执行加密,得到newMd5Password
    // 调用userMapper的updatePasswordByUid()执行更新密码,并获取返回的受影响的行数
    // 判断受影响的行数是否不为1
    // 是:UpdateException
}

具体代码为:

@Override
public void changePassword(Integer uid, String oldPassword, String newPassword, String username) {
    // 日志:输出原密码,新密码
    System.err.println("UserServiceImpl.changePassword()");
    System.err.println("\t原密码:" + oldPassword);
    System.err.println("\t新密码:" + newPassword);
    // 基于参数uid调用userMapper的findByUid()查询用户数据
    User result = userMapper.findByUid(uid);
    // 判断查询结果是否为null
    if (result == null) {
        // 是:抛出UserNotFoundException
        throw new UserNotFoundException(
            "修改密码失败!用户数据不存在!");
    }

    // 判断查询结果中的isDelete是否为1
    if (result.getIsDelete() == 1) {
        // 是:抛出UserNotFoundException
        throw new UserNotFoundException(
            "修改密码失败!用户数据不存在!");
    }

    // 从查询结果中取出盐值
    String salt = result.getSalt();
    // 日志:“将原密码执行加密”
    System.err.println("\t将原密码执行加密");
    // 将参数oldPassword结合盐值执行加密,得到oldMd5Password
    String oldMd5Password = getMd5Password(oldPassword, salt);
    // 日志:输出查询结果中的password
    System.err.println("\t数据库中的密码:" + result.getPassword());
    // 判断oldMd5Password与查询结果中的password是否不一致
    if (!oldMd5Password.equals(result.getPassword())) {
        // 是:PasswordNotMatchException
        throw new PasswordNotMatchException(
            "修改密码失败!原密码错误!");
    }

    // 日志:“将新密码执行加密”
    System.err.println("\t将新密码执行加密");
    // 将参数newPassword结合盐值执行加密,得到newMd5Password
    String newMd5Password = getMd5Password(newPassword, salt);
    // 调用userMapper的updatePasswordByUid()执行更新密码,并获取返回的受影响的行数
    Integer rows = userMapper.updatePasswordByUid(uid, newMd5Password, username, new Date());
    // 判断受影响的行数是否不为1
    if (rows != 1) {
        // 是:UpdateException
        throw new UpdateException(
            "修改密码失败!执行更新密码时出现未知错误!请联系系统管理员!");
    }
}

完成后,在UserServiceTests中编写单元测试:

@Test
public void changePassword() {
    try {
        Integer uid = 15;
        String oldPassword = "1234";
        String newPassword = "8888";
        String username = "密码管理员";
        service.changePassword(uid, oldPassword, newPassword, username);
        System.err.println("OK.");
    } catch (ServiceException e) {
        System.err.println(e.getClass().getName());
        System.err.println(e.getMessage());
    }
}

14. 用户-修改密码-控制器层

(a) 处理新创建的异常

需要处理UpdateException

(b) 设计所需要处理的请求

请求路径:/users/password/change
请求参数:String oldPassword, String newPassword, HttpSession session
请求方式:POST
响应结果:JsonResult<Void>

(c) 处理请求

UserController中添加处理请求的方法:

// http://localhost:8080/users/password/change?oldPassword=0000&newPassword=1234
@RequestMapping("password/change")
public JsonResult<Void> changePassword(String oldPassword, String newPassword, HttpSession session) {
    // 从参数session取出uid和username
    Integer uid = Integer.valueOf(session.getAttribute("uid").toString());
    String username = session.getAttribute("username").toString();
    // 调用业务对象的方法执行修改密码
    service.changePassword(uid, oldPassword, newPassword, username);
    // 返回
    return new JsonResult<>(OK);
}

注意:测试时,必须先登录,然后再执行测试!

15. 用户-修改密码-前端页面

16. 使用拦截器处理登录验证

由于需要登录后才可以执行操作比较多,所以,应该使用拦截器进行统一处理!在处理过程中,如果获取不到用户的登录信息,则可以将用户的请求重定向到登录页面!

首先,应该在cn.tedu.store.interceptor包中创建LoginInterceptor拦截器类,实现HandlerInterceptor接口,重写preHandle()方法,在该方法中验证登录:

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        if (request.getSession()
                .getAttribute("uid") == null) {
            response.sendRedirect("/web/login.html");
            return false;
        }
        return true;
    }

}

在SpringBoot项目中,并没有XML文件用于配置,所以,需要编写配置类来完成拦截器的配置!则在cn.tedu.store.config包中创建InterceptorConfigurer配置类:

@Configuration
public class InterceptorConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        HandlerInterceptor interceptor
            = new LoginInterceptor();

        List<String> patterns = new ArrayList<>();
        patterns.add("/users/reg");
        patterns.add("/users/login");
        patterns.add("/web/register.html");
        patterns.add("/web/login.html");
        patterns.add("/bootstrap3/**");
        patterns.add("/css/**");
        patterns.add("/images/**");
        patterns.add("/js/**");

        registry.addInterceptor(interceptor)
            .addPathPatterns("/**")
            .excludePathPatterns(patterns);
    }

}

17. 用户-修改资料-持久层

(a) 规划所需要执行的SQL语句

关于“修改资料”,应该由2部分功能来组成,分别是“打开页面时就显示当前登录的用户的信息”和“点击修改按钮时执行修改”。

显示当前登录的用户信息应该是根据当前登录的用户id查询用户数据,该查询功能已经完成,无需重复开发!

修改用户资料需要执行的SQL语句大致是:

update t_user set phone=?, email=?, gender=?, modified_user=?, modified_time=? where uid=?

在执行修改之前,依然应该检查用户数据是否存在、是否被标记为已删除,这些检查功能已经完成,无需重复开发!

(b) 接口与抽象方法

UserMapper接口中添加抽象方法:

/**
 * 根据用户的id更新用户基本信息
 * @param user 封装了用户的id和新的信息的对象
 * @return 受影响的行数
 */
Integer updateInfoByUid(User user);

(c) 配置映射

UserMapper.xml中配置以上抽象方法的映射:

<!-- 根据用户的id更新用户基本信息 -->
<!-- Integer updateInfoByUid(User user) -->
<update id="updateInfoByUid">
    UPDATE
        t_user
    SET
        phone=#{phone},
        email=#{email},
        gender=#{gender},
        modified_user=#{modifiedUser},
        modified_time=#{modifiedTime}
    WHERE
        uid=#{uid}
</update>

UserMapperTests中测试:

@Test
public void updateInfoByUid() {
    User user = new User();
    user.setUid(18);
    user.setPhone("13100131001");
    user.setEmail("root@163.com");
    user.setGender(1);
    Integer rows = mapper.updateInfoByUid(user);
    System.err.println("rows=" + rows);
}

18. 用户-修改资料-业务层

(a) 规划可能出现的异常

在处理“打开页面时就显示当前登录的用户的信息”时,可能因为用户数据不存在、数据状态异常而导致失败,则可能抛出UserNotFoundException

在处理“点击修改按钮时执行修改”时,仍需要先检查用户数据是否存在、数据状态是否异常,则可能抛出UserNotFoundException,检查通过后,执行更新时可能抛出UpdateException

以上所有异常都已创建!

(b) 业务接口及抽象方法

IUserService中添加抽象方法:

/**
 * 显示当前登录用户的基本信息
 * @param uid 当前登录的用户的id
 * @return 该用户的基本信息
 */
User showInfo(Integer uid);

/**
 * 修改用户的基本资料
 * @param uid 用户的id
 * @param username 用户名
 * @param user 封装了用户的新资料的对象
 */
void changeInfo(Integer uid, String username, User user);

(c) 实现抽象方法

UserServiceImpl中实现以上抽象方法:

public User showInfo(Integer uid) {
    // 根据参数uid查询用户数据
    // 判断查询结果是否为null
    // 是:抛出UserNotFoundException

    // 判断查询结果中的isDelete是否为1
    // 是:抛出UserNotFoundException

    // 创建新的User对象
    // 将查询结果中的username、phone、email、gender封装到新对象中
    // 返回新User对象
}

public void changeInfo(Integer uid, String username, User user) {
    // 根据参数uid查询用户数据
    // 判断查询结果是否为null
    // 是:抛出UserNotFoundException

    // 判断查询结果中的isDelete是否为1
    // 是:抛出UserNotFoundException

    // 向参数user中封装uid:user.setUid(uid)
    // 向参数user中封装username到modifiedUser属性:user.setModifiedUser(username)
    // 向参数user中封装当前时间到modifiedTime属性:user.setModifiedTime(new Date());
    // 调用持久层userMapper的updateInfoByUid(user)执行更新,获取返回的受影响的行数
    // 判断受影响的行数是否不为1
    // 是:抛出UpdateException
}

具体代码:

@Override
public User showInfo(Integer uid) {
    // 基于参数uid调用userMapper的findByUid()查询用户数据
    User result = userMapper.findByUid(uid);
    // 判断查询结果是否为null
    if (result == null) {
        // 是:抛出UserNotFoundException
        throw new UserNotFoundException(
            "获取用户信息失败!用户数据不存在!");
    }

    // 判断查询结果中的isDelete是否为1
    if (result.getIsDelete() == 1) {
        // 是:抛出UserNotFoundException
        throw new UserNotFoundException(
            "获取用户信息失败!用户数据不存在!");
    }

    // 创建新的User对象
    User user = new User();
    // 将查询结果中的username、phone、email、gender封装到新对象中
    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) {
    // 基于参数uid调用userMapper的findByUid()查询用户数据
    User result = userMapper.findByUid(uid);
    // 判断查询结果是否为null
    if (result == null) {
        // 是:抛出UserNotFoundException
        throw new UserNotFoundException(
            "修改用户资料失败!用户数据不存在!");
    }

    // 判断查询结果中的isDelete是否为1
    if (result.getIsDelete() == 1) {
        // 是:抛出UserNotFoundException
        throw new UserNotFoundException(
            "修改用户资料失败!用户数据不存在!");
    }

    // 向参数user中封装uid:
    user.setUid(uid);
    // 向参数user中封装username到modifiedUser属性:
    user.setModifiedUser(username);
    // 向参数user中封装当前时间到modifiedTime属性:
    user.setModifiedTime(new Date());
    // 调用持久层userMapper的updateInfoByUid(user)执行更新,获取返回的受影响的行数
    Integer rows = userMapper.updateInfoByUid(user);
    // 判断受影响的行数是否不为1
    if (rows != 1) {
        // 是:UpdateException
        throw new UpdateException(
            "修改用户资料失败!执行更新用户资料时出现未知错误!请联系系统管理员!");
    }
}

完成后,在UserServiceTests中测试:

@Test
public void showInfo() {
    try {
        Integer uid = 18;
        User result = service.showInfo(uid);
        System.err.println("OK. " + result);
    } catch (ServiceException e) {
        System.err.println(e.getClass().getName());
        System.err.println(e.getMessage());
    }
}

@Test
public void changeInfo() {
    try {
        Integer uid = 18;
        String username = "资料管理员";
        User user = new User();
        user.setPhone("13900139999");
        user.setEmail("root@qq.com");
        user.setGender(1);
        service.changeInfo(uid, username, user);
        System.err.println("OK.");
    } catch (ServiceException e) {
        System.err.println(e.getClass().getName());
        System.err.println(e.getMessage());
    }
}

19. 用户-修改资料-控制器层

(a) 处理新创建的异常

(b) 设计所需要处理的请求

请求路径:/users/info/show
请求参数:HttpSession session
请求方式:GET
响应结果:JsonResult<User>

(c) 处理请求

// http://localhost:8080/users/info/show
@GetMapping("info/show")
public JsonResult<User> showInfo(HttpSession session) {
    // 从session中获取uid
    Integer uid = Integer.valueOf(session.getAttribute("uid").toString());
    // 调用业务对象的showInfo()方法查询用户数据
    User data = userService.showInfo(uid);
    // 返回OK与以上调用时的返回结果
    return new JsonResult<>(OK, data);
}

20. 用户-修改资料-前端页面

---------------- 以上仅用于复制 ----------------

17. 用户-修改资料-持久层

(a) 规划所需要执行的SQL语句

(b) 接口与抽象方法

(c) 配置映射

18. 用户-修改资料-业务层

(a) 规划可能出现的异常

(b) 业务接口及抽象方法

(c) 实现抽象方法

19. 用户-修改资料-控制器层

(a) 处理新创建的异常

(b) 设计所需要处理的请求

请求路径:
请求参数:
请求方式:
响应结果:JsonResult<?>

(c) 处理请求

20. 用户-修改资料-前端页面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饭九钦vlog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值