基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块

《超市订单管理系统》(第二天) 基于SSM框架的Web项目开发

​ 昨天我们实现了登录功能,但是用的是模拟数据。今天我们要链接数据库整合Spirng+Mybatis,读取数据库中的真实数据,用来跟我们输入的userCode和userPassword进行对比,来判断用户名和密码是否正确。还需要进行一些其他的微调


今日目标:链接数据库完成以下模块设计

  • 完成登录模块(登录页面设计+登录功能)
  • 完成用户退出模块

项目的开发流程(一般来说)

项目的开发流程可以根据具体需求和项目规模有所不同,但通常包括以下主要步骤:

  1. 需求分析和规划
    • 理解项目的需求和目标。
    • 制定项目计划和时间表。
    • 确定项目的范围和功能。
  2. 数据库设计
    • 根据项目需求设计数据库结构,包括表和关系。
    • 创建数据库模式和表结构。
    • 确保数据库的正常运行和性能。
  3. 后端开发
    • 开发后端应用程序,包括业务逻辑和数据访问层。
    • 集成数据库,实现数据的增删改查操作。
    • 编写 API 和服务端逻辑。
  4. 前端开发
    • 开发前端界面和用户体验。
    • 使用 HTML、CSS、JavaScript 等前端技术。
    • 与后端进行通信,调用后端提供的 API。
  5. 集成和测试
    • 集成前后端组件,确保它们协同工作。
    • 进行单元测试和集成测试,检查功能和性能。
    • 解决和修复问题。
  6. 部署和上线
    • 部署应用程序到生产环境。
    • 配置服务器和数据库。
    • 监控应用程序性能,并处理生产问题。
  7. 维护和优化
    • 定期监控和维护应用程序,确保其稳定性。
    • 进行性能优化,提高应用程序效率。
    • 根据用户反馈和需求进行功能扩展和更新。
  8. 文档和培训
    • 编写项目文档,包括用户手册和开发文档。
    • 培训用户和开发团队,确保他们了解项目和工具。

​ 关于数据库的创建,通常在数据库设计阶段会创建数据库模式和表结构但在实际开发中,有时也可以在后期根据需求进行数据库的调整和扩展

这是因为,项目开发是一个迭代和持续改进的过程,需要我们不断地与团队成员者进行沟通和协作。

一般来说都是要提前设计好数据库表结构等,然后再去进行一个前后端的开发。在自己进行一个全新项目开发的时候呢,基本上是得按照上面的流程来。


一、开发前准备

①数据库准备:

运行Navicat for Mysql等数据库管理工具,导入我们项目资源中的数据库文件supermarket.sql

​ ps:Navicat 是一款强大的数据库管理工具,用于管理和维护多种数据库系统,包括 MySQL、MariaDB、SQLite、SQL Server、Oracle 和 PostgreSQL 等。它为数据库开发人员和管理员提供了丰富的功能和工具,使他们能够更轻松地管理和操作数据库。

创建出supermarket数据库。

②查看用户表中的所有字段,我们要确保我们的类中的属性和表中的字段名一致,一 一对应映射,这样涉及到前后端传值的时候就比较清晰,不会太迷糊,降低出错的风险。

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第1张图片

二、开始完善登录功能

自动生成pojo类这个部分,我也是前面的文章有发布过的,可以访问查看一下

如何使用IDEA链接数据库并自动生成POJO类?_Stevedash的博客-CSDN博客如何实现

①确保正确的项目结构和资源文件的齐全

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第2张图片

②使用idea自带链接数据库生成数据库表的pojo类与pojo包下,然后进行检查。

③dao层(dao包)下创建Mybatis的映射文件和接口,我们这里是对user表进行的操作,那么就是UserMapper接口和UserMapper.xml(也就是Mybatis映射文件)

看到这里可能会有疑惑

为什么dao层中的UserMapper接口要和UserMapper.xml的命名一样呢?

​ 其实我们前面的文章也有讲到的,在MyBatis这样的持久化框架中,UserMapper接口和UserMapper.xml的命名之间通常需要保持一致,这是为了确保MyBatis能够正确地将接口与XML配置文件关联起来并执行相应的SQL操作

UserMapper接口代码如下:

package com.steveDash.dao;

import com.steveDash.pojo.User;


public interface UserMapper {
    public User getUserByUserCode(String userCode);
}

UserMapper.xml代码如下:


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.steveDash.dao.UserMapper">

    
    <select id="getUserByUserCode" parameterType="String" resultType="User">
        select * from user where userCode=#{userCode}
    select>
mapper>

这里的返回类型本来是要写全类限名,但是我们在Mybatis-config配置文件中编写了别名,因此这里我们可以直接写User

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第3张图片

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第4张图片

按照我们前面讲的,这里应该还需要去mybatis-config里面注册好我们的mapper映射文件的地址吧?

但是呢,这里我们选择在spring-config中去写入配置Dao层,这样的话我们就不用一个一个的映射文件都要注册到配置文件中,这段代码它会自动扫描该包下的所有映射文件并且注册好

在这里插入图片描述


④根据分层思想,在Service层下,编写UserService接口。

UserService接口中添加查询用户的方法getUserByUserCode()

package com.steveDash.service;

import com.steveDash.pojo.User;

public interface UserService {
    public User getUserByUserCode(String userCode);
}

(使用给接口生成实现类的快捷键ALT+ENTER)编写业务实现类UserServiceImpl

package com.steveDash.service;

import com.steveDash.dao.UserMapper;
import com.steveDash.pojo.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("userServiceImpl")
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;

    public UserMapper getUserMapper() {
        return userMapper;
    }

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public User getUserByUserCode(String userCode) {
        try{
        return userMapper.getUserByUserCode(userCode);
    }catch (RuntimeException e){
            e.printStackTrace();
            throw e;
        }
    }
}

代码说明:在这里我们将dao中的接口UserMapper的实例注入到UserServiceImpl,并调用它的getUserByUserCode方法查询数据

所以这里一定要添加getter,setter方法!!! 因为依赖注入Spring框架通过setter方法来注入userMapper的实例

因为我们是使用注解的方式,所以我们需要去Spring-config.xml中查看一下,是否开启了注解的代码

在这里插入图片描述


⑤打开controller包下的,UserController,进行登录方法doLogin()的修改

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第5张图片

这种方式就是我们前几天学到的,依赖注入和IOC控制反转,由IOC容器创建对象,通过getBean的方式来获取实例对象。


这里请思考一下:下面这俩种写法效果都是一样的,那么为什么我们要选择第一种呢?
UserService userService=(UserServiceImpl)context.getBean("userServiceImpl");

UserServiceImpl userService=(UserServiceImpl)context.getBean("userServiceImpl");

答案如下:

两种方式的效果是一样的,但第一种方式更符合依赖注入和面向接口编程的原则,因为它将userService声明为接口类型,而不是具体的实现类型。这样做有助于降低耦合度,使代码更具灵活性。如果以后更改了UserService的实现类,第一种方式无需修改,而第二种方式则需要修改。因此,第一种方式通常更好一些。


⑥运行一下tomcat服务

测试1首先进行正确的账号密码输入测试:

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第6张图片

可以看到正常运行,并且没有错误。

还需要进行其他情况的测试2,比如用户名不存在的情况admin1,预期输出结果:用户名错误

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第7张图片

与预期结果一致。

那么在进行登录测试3:账号正确,密码错误的情况。预期结果:用户名或者密码错误

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第8张图片

与预期结果一致。


⑦代码反思优化,采用依赖注入的方式

上面的代码还有优化的空间,因为

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第9张图片

蓝色标注的这一段,我们只是为了获取userServiceImpl的Bean,所以我们可以使用依赖注入的方式,代码如下:

package com.steveDash.controller;

import com.steveDash.pojo.User;
import com.steveDash.service.UserService;
import com.steveDash.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

@Controller
public class UserController {
    @Resource
    private UserService userService;

    @RequestMapping(value="/login")
    public String showLoginPage(){
        System.out.println("进入登录页面");
        return "login";
    }

    @RequestMapping(value="/dologin")
    public String doLogin(@RequestParam("userCode") String userCode, @RequestParam("userPassword") String userPassword, Model model, HttpSession session){
        //读取用户和密码
        System.out.println("帐号和密码是"+userCode+"-"+userPassword);
        User user=userService.getUserByUserCode(userCode);
        if(user!=null){
        if(userPassword.equals(user.getUserPassword())){
           session.setAttribute("userCode",userCode);//添加session值
            return "welcome"; //密码正确就去welcome.jsp
        }else{
            //登录失败就回到login.jsp
            model.addAttribute("error", "用户名或密码不正确");
            return "login";
        }
    }else{
        //登录失败就返回login.jsp
            model.addAttribute("error", "用户名不正确");
            return "login";
        }
    }

}

⑧重新运行服务,看看需求是否满足,登录功能是否正常?

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第10张图片

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第11张图片


三、完成退出模块

​ 退出登录模块的设计,其实就是清除httpSession中的Session,然后进行判断若是Session中没有用户,那就判断回到登录页面,若有就跳转到主功能页面,这样子就可以完成一个退出的功能。

所以在完成退出模块设计前,要对我们刚刚实现的登录功能进行一个优化

①我们Session中只存了用户的账号名:userCode,可是我们其他页面或许需要user用户的其他参数,因此我们修改Session中存储的值,修改为存储user用户

在UserController.java找到doLogin并且进行修改

@RequestMapping(value="/dologin")
public String doLogin(@RequestParam("userCode") String userCode, @RequestParam("userPassword") String userPassword, Model model, HttpSession session){
    //读取用户和密码
    System.out.println("帐号和密码是"+userCode+"-"+userPassword);
    User user=userService.getUserByUserCode(userCode);
    if(user!=null){
    if(userPassword.equals(user.getUserPassword())){
       session.setAttribute("user",user);//添加session值,修改成存入user对象
        return "redirect:/main"; //密码正确就去welcome.jsp(main是welcome页面的映射)
    }else{
        //登录失败就回到login.jsp
        model.addAttribute("error", "用户名或密码不正确");
        return "login";
    }
}else{
    //登录失败就返回login.jsp
        model.addAttribute("error", "用户名不正确");
        return "login";
    }
}

所以我们还需要添加一个去到welcome页面的映射,因此还是在UserController中进行如下操作

新增/main映射到welcome.jsp页面

@RequestMapping(value="/main")
public String welcome(HttpSession session)  {
    if(session.getAttribute("user") == null){ //如果用户没有登录就直接来到main.html就回到login
        return "redirect:/syserror";
    }
    else
        return "welcome";
}

 @RequestMapping("/syserror")//出错页面
    public String sysError(){
        return "syserror";
    }

​ 这里为什么不是直接使用welcome作为页面的映射呢?这是基于一个网络安全的考虑,因为直接让映射名和文件名一致的话,很容易就被黑客找到关键资源文件,进行渗透攻击修改后台数据,因此我们都是用关键词代表这个映射的操作。

​ 我们这里还加入了一个判断,若是没有登陆就想直接访问main界面,就会自动重定向到syserror.jsp报错页面

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2023/9/17
  Time: 11:39
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
</head>
<body>
<h1>请登录后再访问该页面!</h1>
<a href="${pageContext.request.contextPath }/login">返回</a>
</body>
</html>

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第12张图片

**基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第13张图片
**

上面这样子就完善了登录页面的操作,并且设置了主页welcome的main映射,然后还编写了未登录就访问主页的错误提示。


②编写退出操作

代码如下:

@RequestMapping(value = "/logout")
public String logout(HttpSession session){
    session.removeAttribute("user");//清除掉Session 中的user值
    return "redirect:/login";//返回login.jsp
}

使用removeAttribute()方法清除掉session中存储的user对象,然后重定向到登录界面即可完成退出操作。

重新运行服务看看效果

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第14张图片

基于SSM框架的《超市订单管理系统》Web项目开发(第二天)完成登录模块和用户退出模块_第15张图片

可以看到了退回了登录界面,退出功能也完成了。


总结

​ 今天是综合项目超市订单管理系统开发的第二天,我们完善了登录的功能模块和退出的功能模块。项目现在已经整合了SpringMVC和Spring、以及Mybatis,算是SSM的综合项目了,接下里的就是把之前学习过的知识,应用在这个项目中还讲解了一下项目的开发流程,希望通过今天的学习,希望各位读者可以对整体的项目开发流程有个大致的了解,为框架开发打下坚实基础。

​ 想要跟着学习的可以去我的资源里面找对应的文件下载,我的md文件也会发上去,项目文件会上传可以自己跟着学习一下。(ps:前俩天有事,所以今天补上)

作者:Stevedash

发表于:2023年9月17日 13点23分

注:本文内容基于个人学习理解,如有错误或疏漏,欢迎指正。感谢阅读!如果觉得有帮助,请点赞和分享。

你可能感兴趣的:(JAVA企业级应用开发必学框架,综合项目的开发,SSM框架的学习,前端,java,intellij-idea,ssm,综合项目开发)