基于springboot框架的电脑商城项目(二)

简介: 用户登录当用户输入用户名和密码将数据提交给后台数据库进行查询,如果存在对应的用户名和密码则表示登录成功,登录成功之后跳转到系统的主页就是index.html页面,跳转在前端使用jquery来完成。(一)登录(持久层)1.规划sql语句依据用户提交的用户名和密码做select查询。

用户登录

当用户输入用户名和密码将数据提交给后台数据库进行查询,如果存在对应的用户名和密码则表示登录成功,登录成功之后跳转到系统的主页就是index.html页面,跳转在前端使用jquery来完成。

(一)登录(持久层)

1.规划sql语句

依据用户提交的用户名和密码做select查询。

select * from t_user where username=?

2.设计接口和抽象方法

在UserMapper接口的findByUsername方法已经实现了这个方法

(二)登录(业务层)

1.异常规划

用户不存在UsernameNotFoundException异常(运行时异常

public class UsernameNotFoundException extends ServiceException {
    /**重写ServiceException的所有构造方法*/
}

密码错误PasswordNotMatchException异常(运行时异常

public class PasswordNotMatchException extends ServiceException{
    /**重写ServiceException的所有构造方法*/
}

2.设计接口和抽象方法及实现

在IUserService接口中编写抽象方法login(String username,String password)login(User user)也是可以的

   //登录
    User login(String username,String password);

在UserServiceimpl中实现该方法

@Override
    public User login(String username, String password) {
        //根据用户名称来查询用户的数据是否存在,不存在则抛出异常
        User result = userMapper.findByUsername(username);
        if (result == null) {
            throw new UsernameNotFoundException("用户数据不存在");
        }
        /**
         * 检测用户的密码是否匹配:
         * 1.先获取数据库中加密之后的密码
         * 2.和用户传递过来的密码进行比较
         *  2.1先获取盐值
         *  2.2将获取的用户密码按照相同的md5算法加密
         */
        String oldPassword = result.getPassword();
        String salt = result.getSalt();
        String newMd5Password = getMD5Password(password, salt);
        if (!newMd5Password.equals(oldPassword)) {
            throw new PasswordNotMatchException("用户密码错误");
        }
        //判断is_delete字段的值是否为1,为1表示被标记为删除
        if (result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户数据不存在");
        }
        //方法login返回的用户数据是为了辅助其他页面做数据展示使用(只会用到uid,username,avatar)
        //所以可以new一个新的user只赋这三个变量的值,这样使层与层之间传输时数据体量变小,后台层与
        // 层之间传输时数据量越小性能越高,前端也是的,数据量小了前端响应速度就变快了
        User user = new User();
        user.setUid(result.getUid());
        user.setUsername(result.getUsername());
        user.setAvatar(result.getAvatar());
        return user;
    }

(三)登录(控制层)

1.处理异常

业务层抛出的异常需要在统一异常处理类中进行统一的捕获和处理,如果该异常类型已经在统一异常类中曾经处理过则不需要重复添加

    }else if (e instanceof UsernameNotFoundException){
            result.setState(5001);
            result.setMessage("用户不存在");
        }else if (e instanceof PasswordNotMatchException){
            result.setState(5002);
            result.setMessage("密码错误");
        }

2.请求设计

请求路径:/users/login

请求参数:String username,String password

请求类型:POST

响应结果:JsonResult< User>

3.请求处理

在UserController类中编写处理请求的方法.编写完成后启动主服务验证一下

   @PostMapping("/login/{username}/{password}")
    public JsonResult<User> login(@PathVariable String username,@PathVariable String password){
       User user=userService.login(username,password);
       return new JsonResult<User>(ok,user);
    }

注意,控制层方法的参数是用来接收前端数据的,接收数据方式有两种:

请求处理方法的参数列表设置为非pojo类型:

SpringBoot会直接将请求的参数名和方法的参数名直接进行比较,如果名称相同则自动完成值的依赖注入

请求处理方法的参数列表设置为pojo类型:

SpringBoot会将前端的url地址中的参数名和pojo类的属性名进行比较,如果这两个名称相同,则将值注入到pojo类中对应的属性上

这两种方法都没有使用注解等等花里胡哨的,却能正常使用,原因是springboot是约定大于配置的,省略了大量配置以及注解的编写

(四)登录(前端)

1.前端页面代码

在login.html中编写前端代码

<script type="text/javascript">
      //1.监听按钮是否被点击
      $("#btn-login").click(function () {
        $.ajax({
          url:"/users/login",
          type:"POST",
          data:$("#form-login").serialize(),
          dataType:"JSON",
          //2.发送ajax()的异步请求来完成用户的注册功能
          success:function (json) {
            if (json.state==200){
              alert("登录成功");
              //跳转系统主页index。html
              //相对路径
              location.href="index.html";
            }else{
              alert("登录失败");
            }
          },
          error:function (xhr) {
            alert("登录产生未知异常"+xhr.message);
          }
        });
      });
    </script>

2.用户会话session

session对象主要存在服务器端,可以用于保存服务器的临时数据的对象,所保存的数据可以在整个项目中都可以通过访问来获取,把session的数据看做一个共享的数据。首次登录的时候所获取的用户的数据,转移到session对象即可。seession.getAttrbute(“key”)可以将获取session中的数据这种行为进行封装,封装在BaseController类中。

1.封装session对象中数据的获取(封装父类中)、数据的设置(当用户登录成功后进行数据的设置,设置到全局的session对象)。

2.在父类中封装两个数据:获取uid和获取username对应的两个方法。用户头像暂时不考虑,将来封装cookie中来使用。

 //获取当前登录的id
    protected final Integer getuidfromsession(HttpSession session){
        return Integer.valueOf(session.getAttribute("uid").toString());
    }
//获取当前登录用户名
    protected final String getusernamesession(HttpSession session){
        return session.getAttribute("username").toString();
    }

3.在登录的方法中将数据封装在session对象中。服务本身自动创建有session对象,已经是一个全局的session对象。SpringBoot直接使用session对象,直接将HttpSession类型的的对象做为请求处理方法的参数,会自动将全局的session对象注入到请求处理方法的session形参上。

   @PostMapping("/login")
    public JsonResult<User> login(String username, String password, HttpSession session){
       User user=userService.login(username,password);
       session.setAttribute("uid",user.getUid());
       session.setAttribute("username",user.getUsername());
       return new JsonResult<User>(ok,user);
    }

(五)拦截器

拦截器:首先将所有的请求统一拦截到拦截器中,可以拦截器中来定义过滤的规则,如果不满足系统的设置的过滤规则,统一的处理是重新去打开login.html页面(重定向和转发),推荐使用重定向(重定向和转发都是资源的跳转,前者是在浏览器端跳转,会产生两次请求,地址栏url会变化,后者转发是在服务器端跳转,且只会产生一次请求,地址栏url不会变化)

在SpringBoot项目中拦截器的定义和使用。SpringBoot是依靠springMVC来完成的。SpringMVC提供了一个HandlerInterceptor接口,用于表示定义一个拦截器。首先自定义个类,在这个类实现这个接口。

1.首先自定义一个类,在这个类实现这个Handlerlnterceptor接口。

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
     // 读取session对象
        Object obj=request.getSession().getAttribute("uid");
        if (obj==null){
            //说明用户没有登录过,则重定向到login。html
            response.sendRedirect("/web/login.html");
            //结束后续调用
            return false;
        }
        //请求放行
        return true;
    }
}

源码分析

public interface HandlerInterceptor {
//在调用所有处理请求的方法之前被自动调用执行的方法
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
//在ModelAndView对象返回之后被调用的方法
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }
//在整个请求所关联的资源被执行完毕最后执行的方法
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

注册过滤器:添加白名单(哪些资源可以在不登录的情况下访问:
login.htmllregister.htmNlogin(reglindex.htm/product.html)、添加黑名单(在用户登录的状态才可以访问的页面资源)。

注册过滤器的技术:借助WebMvcConfigure接口,可以将用户定义的拦截器进行注册,才可以保证拦截器能够生效和使用。定义一个类,然后让这个类实现WebMvcConfigure接口。配置信息,建议存放在项目的config包结构下。

//处理器拦截器的注册
@Configuration
public class LoginInterceptorConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        HandlerInterceptor interceptor=new LoginInterceptor();
        List<String> patterns=new ArrayList<>();
        patterns.add("/bootstrap3/**");
        patterns.add("/css/**");
        patterns.add("/images/**");
        patterns.add("/js/**");
        patterns.add("/web/register.html");
        patterns.add("/web/login.html");
        patterns.add("/web/index.html");
        patterns.add("/web/product.html");
        patterns.add("/users/reg");
        patterns.add("/users/login");
      //完成拦截器注册
        registry.addInterceptor(interceptor).addPathPatterns("/**")
                .excludePathPatterns(patterns);
    }
}

修改密码

需要用户提交原始密码和新密码,再根据当前登录的用户进行信息的修改操作

(一)修改密码(持久层)

1.sql规划

根据用户的uid修改用户password值

update t_user set password=?,modified_user=?, modified_time=? WHERE uid=?

在执行修改密码之前,还应检查用户数据是否存在或者用户数据是否被标记为"已删除"、并检查原密码是否正确,这些检查都可以通过查询用户数据来辅助完成

SELECT * FROM t_user WHERE uid=?

2.设计接口和抽象方法

mapper接口

     //根据uid修改密码
    Integer updatePasswordByUid(Integer uid, String password, String modifiedUser, Date modifiedTime);
    //根据uid查询
    User findUid(Integer uid);

mapper.xml映射文件

    <update id="updatePasswordByUid">
update t_user set password=#{password},
                  modified_user=#{modifiedUser},
                  modified_time=#{modifiedTime}
           where uid=#{uid}
    </update>
    <select id="findUid" resultMap="UserEntityMap">
select * from t_user where uid=#{uid}
    </select>

(二)修改密码(业务层)

1.规划异常

1.用户的源密码错误,is_delete==1、uid找不到,在用户没有发现的异常。2.update在更新的时候,有可能产生未知的异常,UpdateException。

//更新时产生异常
public class UpdateException extends ServiceException{
 /**重写ServiceException的所有构造方法*/
    }

2.设计接口和抽象方法

执行用户修改密码的核心方法。

    //修改密码
   void changePassword(Integer uid,String username,String oldPassword,String newPassword);

serviceimpl实现该方法

    @Override
    public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
      User user=userMapper.findUid(uid);
if (user==null || user.getIsDelete()==1){
    throw new UsernameNotFoundException("用户不存在");
}
//密码比较
String salt=user.getSalt();
String oldpassword2=getMd5Password(oldPassword,salt);
if (!oldpassword2.equals(user.getPassword())){
    throw new PasswordNotMatchException("密码不正确");
}
//将新密码设置进去
String newpassword2=getMd5Password(newPassword,salt);
user.setPassword(newpassword2);
Integer rows= userMapper.updatePasswordByUid(uid,newpassword2,user.getUsername(),new Date());
   if (rows!=1){
       throw new UpdateException("修改时出现未知异常");
   }
    }

三)修改密码(控制层)

1.异常处理

UpdateException需要配置在统一的异常处理方法中。(basecontroller中)

   }else if (e instanceof UpdateException){
            result.setState(5001);
            result.setMessage("修改出现异常");
        }

2.设计请求

请求路径:/users/change_password

请求类型:post

请求参数:String oldPassword,String newPassword,HttpSession session(uid和username可以通过session获取到,在处理方法的内部获取就可以了)如果参数名用的是非pojo类型,就需要和表单中的name属性值保持一致

响应结果:JsonResult< void>

3.处理请求

@PostMapping("/change_password")
    public JsonResult<Void> update(String oldPassword,String newPassword,HttpSession session){
    Integer getuidfromsession = getuidfromsession(session);
    String getusernamesession = getusernamesession(session);
    userService.changePassword(getuidfromsession,getusernamesession,oldPassword,newPassword);
    return new JsonResult<>(ok);
}

(四)修改密码(前端页面)

在password.html中添加ajax请求的处理

<script type="text/javascript">
      //1.监听按钮是否被点击
      $("#btn-change-password").click(function () {
        $.ajax({
          url:"/users/change_password",
          type:"POST",
          data:$("#form-change-password").serialize(),
          dataType:"JSON",
          //2.发送ajax()的异步请求来完成用户的注册功能
          success:function (json) {
            if (json.state==200){
              alert("密码修改成功");
              //跳转系统主页index。html
              //相对路径
              location.href="login.html";
            }else{
              alert("密码修改失败失败");
            }
          },
          error:function (xhr) {
            alert("修改密码产生未知异常"+xhr.message);
          }
        });
      });
    </script>

后记

👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹

相关文章
|
11天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的服装商城管理系统
基于Java+Springboot+Vue开发的服装商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的服装商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
33 2
基于Java+Springboot+Vue开发的服装商城管理系统
|
21天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
176 37
|
9天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的蛋糕商城管理系统
基于Java+Springboot+Vue开发的蛋糕商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的蛋糕商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
21 3
基于Java+Springboot+Vue开发的蛋糕商城管理系统
|
18天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的母婴商城管理系统
基于Java+Springboot+Vue开发的母婴商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的网上母婴商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
28 7
基于Java+Springboot+Vue开发的母婴商城管理系统
|
19天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的农产品商城管理系统
基于Java+Springboot+Vue开发的农产品商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。 通过学习基于Java的农产品商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
46 5
基于Java+Springboot+Vue开发的农产品商城管理系统
|
20天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的体育用品商城管理系统
基于Java+Springboot+Vue开发的体育用品商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的体育用品商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
25 2
基于Java+Springboot+Vue开发的体育用品商城管理系统
|
11天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
557 8
|
9天前
|
XML 前端开发 Java
控制spring框架注解介绍
控制spring框架注解介绍
|
9天前
|
存储 NoSQL Java
Spring Session框架
Spring Session 是一个用于在分布式环境中管理会话的框架,旨在解决传统基于 Servlet 容器的会话管理在集群和云环境中的局限性。它通过将用户会话数据存储在外部介质(如数据库或 Redis)中,实现了会话数据的跨服务器共享,提高了应用的可扩展性和性能。Spring Session 提供了无缝集成 Spring 框架的 API,支持会话过期策略、并发控制等功能,使开发者能够轻松实现高可用的会话管理。
Spring Session框架
|
16天前
|
Java 应用服务中间件 开发者
深入探索并实践Spring Boot框架
深入探索并实践Spring Boot框架
27 2
下一篇
无影云桌面