Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

作者:天海奈奈 时间:2022-07-15 10:19:25 

项目演示

演示中只用一个用户登录,只是为了测试功能,实际使用中是根据数据库表内数据来决定的。

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

1 创建工程完成配置

1 ieda新建maven项目名字随便起

2 点击文件,项目 ,模块 ,点加号添加web模块 ,这里要注意文件路径

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

我们改一下第一项的路径 从web 改成src\main\webapp

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

下面Web资源目录也改一下

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

选择webapp 点击右下角创建工件系统自动创建工件,点确认

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

发现我们webapp有个小蓝点就算成功了。

这个时候先在java包下建一个test类构建一下项目,看一下target包出来没,如果先配置tomcat target得后期手动拉出来,很麻烦。

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

现在开始配tomcat 点击右上角添加配置

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

点击加号选择tomcat本地

点击配置,主目录放我们tomcat的文件夹,系统会自动生成其他的

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

完成后点右下角的小红灯泡配置工件,进去后不用动,把下面的应用程序上下文改为 “/” 就行。

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

点击确认。 为了验证配置是否可用进入webapp目录下,新建一个index.html

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Test</title>
</head>
<body>
<h1> 配置完成,终于可以开始了</h1>
</body>
</html>

点击gebug启动tomcat ,根据之前的端口在浏览器看看有没有我们写的网页

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

如果网页显示正常我们开始添加依赖和写配置文件。

pom.xml 这里只显示需要加的,每个依赖我也标上了注释

<repositories>
       <repository>
           <id>aliyun</id>
           <name>aliyun</name>
           <url>https://maven.aliyun.com/repository/public</url>
       </repository>
   </repositories>
   <dependencies>
       <!--        webmvc-->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>5.3.8</version>
       </dependency>
       <!--        json序列化-->
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-annotations</artifactId>
           <version>2.12.3</version>
       </dependency>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-core</artifactId>
           <version>2.9.9</version>
       </dependency>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
           <version>2.9.9</version>
       </dependency>
       <!--        JDBC-->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-jdbc</artifactId>
           <version>5.3.8</version>
       </dependency>
       <!--        mybatis-plus 自动引入mybatis-->
       <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>mybatis-plus</artifactId>
           <version>3.4.3.1</version>
       </dependency>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.16</version>
       </dependency>
       <!--        druid 连接池-->
       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid</artifactId>
           <version>1.2.6</version>
       </dependency>
       <!--        junit单元测试-->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-test</artifactId>
           <version>5.3.8</version>
       </dependency>
       <!--        javax.servlet-->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>javax.servlet-api</artifactId>
           <version>3.1.0</version>
           <scope>provided</scope>
           <!--只在测试时用-->
       </dependency>
       <!--        日志组件-->
       <dependency>
           <groupId>ch.qos.logback</groupId>
           <artifactId>logback-classic</artifactId>
           <version>1.2.3</version>
       </dependency>
       <!--   MD5加密组件-->
       <dependency>
           <groupId>commons-codec</groupId>
           <artifactId>commons-codec</artifactId>
           <version>1.15</version>
       </dependency>
       <dependency>
           <groupId>org.jsoup</groupId>
           <artifactId>jsoup</artifactId>
           <version>1.12.1</version>
       </dependency>
   </dependencies>

在resources下新建applicationContext.xml 来作为配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:task="http://www.springframework.org/schema/task"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/task
           http://www.springframework.org/schema/task/spring-task.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd">
   <!--    组件扫描,完成对象的创建与初始化  base-package写自己的 -->
   <context:component-scan base-package="com.xatu"/>
   <!--    开启注解模式-->
   <mvc:annotation-driven>
       <!--        消息转换器-->
       <mvc:message-converters>
           <bean class="org.springframework.http.converter.StringHttpMessageConverter">
               <!--设置属性 媒体类型(list集合)-->
               <property name="supportedMediaTypes">
                   <list>
                       <value>application/json;charset=utf-8</value>
                   </list>
               </property>
           </bean>
       </mvc:message-converters>
   </mvc:annotation-driven>
   <!--    把静态资源排除在外-->
   <mvc:default-servlet-handler/>
   <!--MyBatis与Spring的整合配置 -->
   <!--1.配置数据源-->
   <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
       <!--        实例化DruidDataSource设置与连接相关的属性-->
       <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
       <!--        jdbc驱动-->
       <property name="url" value="jdbc:mysql://localhost:3306/cnpc_comment?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
       <!--        URL连接字符串   用户名密码写自己mysql数据库的账号密码-->
       <property name="username" value="******"/>
       <!--        用户名-->
       <property name="password" value="******"/>
       <!--        密码-->
       <property name="initialSize" value="5"/>
       <!--        初始化时几个数据库连接,初始数量-->
       <property name="maxActive" value="20"/>
       <!--        最大数量-->
   </bean>
   <!--2.配置SessionFactoryBean-->
   <!--SqlSessionFactoryBean用于根据配置信息创建SqlSessionFactory,不再需要我们自己编码创建-->
   <!--   没有引入mybatis-plus之前的 <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">-->
   <bean id="sessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
       <property name="dataSource" ref="dataSource"/>
       <!--        数据源  ref关联到 上面的dataSource对象-->
       <property name="mapperLocations" value="classpath:mappers/*.xml"/>
       <!--        加载对象过程中扫描哪个文件 保存sql文件的xml-->
       <property name="configLocation" value="classpath:mybatis-config.xml"/>
       <!--        本身框架配置文件路径-->
       <!-- MyBaits Plus 3.4以后版本需要在MybatisSqlSessionFactoryBean.plugins属性中进行设置 -->
       <property name="plugins">
           <array>
               <bean class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
                   <property name="interceptors">
                       <list>
                           <bean class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor"/>
                       </list>
                   </property>
               </bean>
           </array>
       </property>
       <!--        插件配置项 代表一系列插件,
       实例化一个MybatisPlusInterceptor插件容器
       用interceptors进行指定
                  -->
   </bean>
   <!--3.配置Mapper扫描器   value 写自己mapper的位置-->
   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <property name="basePackage" value="com.xatu.mapper"/>
   </bean>
   <!--    声明式事务配置-->
   <!--    1,定义事务管理器-->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <property name="dataSource" ref="dataSource"/>
   </bean>
   <!--    2,开启注解模式的声明式事务-->
   <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

mybatis.config

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <!--    驼峰命名转换-->
   <settings>
       <setting name="mapUnderscoreToCamelCase" value="true"/>
   </settings>
   <!-- MyBatis Plus 3.4版本以前配置分页插件 -->
   <!--<plugins>
       <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin>
   </plugins>-->
</configuration>

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
       <!--向控制台书写日志的追加器-->
       <encoder>
           <pattern>%d{HH:mm:ss} %-5level [%thread] %logger{30} - %msg%n</pattern>
           <!-- 线程名字,产生日志的时间,日志的级别,由哪个类产生的日志-->
           <charset>GBK</charset>
       </encoder>
   </appender>
   <root level="debug">
       <!-- 最低允许输出debug级别的日志,日志向控制台进行输出-->
       <appender-ref ref="console"/>
   </root>
</configuration>

mappers包下的manager.xml 他要跟自己的mapper包进行绑定 由于用的mybatis-plus所以不用自己写语句

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xatu.mapper.">
</map

基本配置就完成了

2 表设计

表名叫manager (实体类要绑定的注意)

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

3 实体类

@TableName("manager")
public class Manager {
   @TableId(type = IdType.AUTO)
   private Long managerId;
   private String username;
   private String password;
   private Integer salt;
   @Override
   public String toString() {
       return "Manager{" +
               "userId=" + managerId +
               ", username='" + username + '\'' +
               ", password='" + password + '\'' +
               ", salt=" + salt +
               '}';
   }
   public Long getUserId() {
       return managerId;
   }
   public void setUserId(Long userId) {
       this.managerId = userId;
   }
   public String getUsername() {
       return username;
   }
   public void setUsername(String username) {
       this.username = username;
   }
   public String getPassword() {
       return password;
   }
   public void setPassword(String password) {
       this.password = password;
   }
   public Integer getSalt() {
       return salt;
   }
   public void setSalt(Integer salt) {
       this.salt = salt;
   }
}

4 mapper

public interface ManagerMapper extends BaseMapper<Manager> {
}

5 service

public interface ManagerService {
   public Manager checkLogin1(String username, String password);
}

Impl 实现类

先使用mapper查看是否用这个用户名的用户再调用用户表的信息来判断密码是否正确,我们这里假设没有重名用户。

@Service
//默认方法不开启事务
@Transactional(propagation = Propagation.NOT_SUPPORTED,readOnly = true)
public class ManagerServiceImpl implements ManagerService {
   @Resource
   private ManagerMapper managerMapper;
   @Transactional(rollbackFor = Exception.class)
   @Override
   public Manager checkLogin1(String username, String password) {
       QueryWrapper<Manager> wrapper = new QueryWrapper();
       wrapper.eq("username", username);
       Manager manager = managerMapper.selectOne(wrapper);
       if (manager == null) {
           throw new MemberException("用户不存在");
       }
       String md5 = MD5Utils.md5Digest(password, manager.getSalt());
       if (!md5.equals(manager.getPassword())) {
           throw new MemberException("您输入的密码有误");
       }
       return manager;
   }
}

异常

public class MemberException extends RuntimeException{
   public MemberException(String message){
       super(message);
   }
}

6 controller

调用service的chedkLogin1方法来检验登录 为了安全,在成功登录后我们将密码 和盐值 设为null

@RestController
@RequestMapping("/api/manager")
public class ManagerController {
   @Resource
   private ManagerService managerService;
   @PostMapping("/check_login1")
   public ResponseUtils checkLogin1(String username , String password){
       ResponseUtils resp ;
           resp = new ResponseUtils();
           try {
               Manager manager = managerService.checkLogin1(username, password);
               manager.setPassword(null);
               manager.setSalt(null);
               resp = new ResponseUtils().put("manager" , manager);
           }catch (Exception e){
               e.printStackTrace();
               resp = new ResponseUtils(e.getClass().getSimpleName(), e.getMessage());
           }
       return resp;
   }
}

7 工具类

MD5

用来使用hash算法使密码变复杂

public class MD5Utils {
   public static String md5Digest(String source ,Integer salt){
       char[] ca = source.toCharArray();
       for(int i = 0 ; i < ca.length ;i++){
           ca[i] = (char) (ca[i] + salt);
       }
       String target = new String(ca);
       String md5 = DigestUtils.md5Hex(target);
       return md5;
   }
}

统一返回对象

public class ResponseUtils {
   private String code;//服务处处理编码
   private String message;//服务器返回消息
   private Map data = new LinkedHashMap<>();//服务器返回的数据
   //成功
   public ResponseUtils(){
       this.code = "0";
       this.message = "success";
   }
   //失败,传入编码和消息
   public ResponseUtils(String code , String message){
       this.code = code;
       this.message = message;
   }
   //给data进行赋值
   public ResponseUtils put(String key , Object value){
       this.data.put(key, value);
       return this;
   }
   public String getCode() {
       return code;
   }
   public void setCode(String code) {
       this.code = code;
   }
   public String getMessage() {
       return message;
   }
   public void setMessage(String message) {
       this.message = message;
   }
   public Map getData() {
       return data;
   }
   public void setData(Map data) {
       this.data = data;
   }
}

整体

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

8 前端页面

我们是有vue 并且使用element-plus组件库来简化和美化我们的页面

Spring整合SpringMVC与Mybatis(SSM)实现完整登录功能流程详解

这里我选择的是创建静态文件包,里面放着常用文工具,需要的时候直接把包放在webapp下载页面编写时进行调用。没有的话请选择替他方法,方法很多。

login.html

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>登录</title>
   <!-- 引入样式 -->
   <link rel="stylesheet" type="text/css" href="assets/element-plus/index.css" rel="external nofollow" >
   <!-- 引入组件库 -->
   <script src="/assets/vue/vue.global.js"></script>
   <script src="/assets/element-plus/index.full.js"></script>
   <script src="/assets/axios/axios.js"></script>
   <style>
       .login-box {
           border: 1px solid #DCDFE6;
           width: 350px;
           margin: 180px auto;
           padding: 35px 35px 15px 35px;
           border-radius: 5px;
           -webkit-border-radius: 5px;
           -moz-border-radius: 5px;
           box-shadow: 0 0 25px #909399;
       }
       .login-title{
           text-align: center;
           margin: 0 auto 40px auto;
           color: #303133;
       }
   </style>
</head>
<body>
<div id="app">
   <el-form ref="loginForm" label-width="80px" :rules="rules" :model="form" class="login-box">
       <h2 class="login-title">登录</h2>
       <el-form-item label="账号" prop="username">
           <el-input type="text" placeholder="请输入账号" v-model="form.username"></el-input>
       </el-form-item>
       <el-form-item label="密码" prop="password">
           <el-input type="password" placeholder="请输入密码" v-model="form.password"></el-input>
       </el-form-item>
       <el-form-item>
           <el-button type="primary" v-on:click="onSubmit('loginForm')" style="width:200px">登录</el-button>
       </el-form-item>
       <el-form-item>
           <el-button type="primary" v-on:click="returnBack" style="width:200px">退出</el-button>
       </el-form-item>
   </el-form>
</div>
<script>
   const Main = {
       data() {
           return {
               form: {
                   username: ''
                   ,password: ''
               }
               ,rules:{
                   username: [
                       {required: true,message : '账号不能为空' , trigger:'blur'}
                   ],
                   password:[
                       {required: true,message : '密码不能为空' , trigger:'blur'}
                   ]
               }
           }
       }
       ,methods : {
           onSubmit(formName){
               const objApp = this;
               const form = this.$refs[formName];
               form.validate((valid) => {
                   if(valid){
                       console.info("表单校验成功,准备提交数据");
                       const form = this.form;
                       const $message = this.$message;
                       const params = new URLSearchParams();
                       params.append("username", form.username);
                       params.append("password", form.password);
                       axios.post("/api/manager/check_login1", params)
                           .then(function (response) {
                           console.info(response);
                           const json = response.data;
                           if(json.code=="0"){
                               window.location.href = "/index1.html";
                           }else{
                               $message.error({message:json.message, offset: 100});
                           }
                       });
                   }
               })
           }
           ,returnBack : function (){
               window.location.href = "/index.html";
           }
       }
   };
   //初始化Vue,绑定Main中的数据,利用ElementPlus对#app容器进行重新渲染
   const app = Vue.createApp(Main);
   app.use(ElementPlus);
   app.mount("#app");
</script>
</body>
</html>

至于另外两个页面,只是使用a标签添加链接 因为只是登录功能没有下一步所以建立两个网页来判断跳转与登录是否成功

来源:https://blog.csdn.net/weixin_57169969/article/details/126817509

标签:Spring,SpringMVC,Mybatis,登录功能
0
投稿

猜你喜欢

  • 实现一个基于Servlet的hello world程序详解步骤

    2022-06-21 00:22:13
  • Android自定义Banner轮播效果

    2023-08-05 23:34:06
  • C语言new操作的安全性分析

    2021-09-07 05:22:20
  • Spring Boot中的Properties的使用详解

    2021-07-02 07:25:22
  • Android使用Room操作数据库流程详解

    2023-03-21 21:00:31
  • Opencv实现读取摄像头和视频数据

    2023-07-16 15:19:58
  • 基于Mybatis-Plus的CRUD的实现

    2023-09-10 14:38:45
  • Quartz.Net使用方法详解

    2023-08-17 11:50:54
  • C#基于简单工厂模式实现的计算器功能示例

    2023-06-19 12:40:10
  • java生成json数据示例

    2023-10-30 04:06:45
  • Unity动画混合树实例详解

    2022-06-17 14:41:27
  • Java解析Excel内容的方法

    2023-03-20 20:36:26
  • SpringBoot之导入静态资源详解

    2021-06-22 05:01:30
  • python调用java模块SmartXLS和jpype修改excel文件的方法

    2023-06-11 16:59:21
  • Android仿微信朋友圈图片查看器

    2023-01-27 18:07:20
  • Spring Boot 与DBunit 配合使用方法

    2022-07-29 13:29:28
  • Java URL自定义私有网络协议

    2021-08-11 02:21:06
  • Java IO之File 类详解

    2023-08-07 20:02:12
  • c# 用Dictionary实现日志数据批量插入

    2022-05-29 02:01:45
  • Java实现替换PDF中的字体功能

    2023-10-04 13:24:17
  • asp之家 软件编程 m.aspxhome.com