• [Spring实战] 整合Spring/SpringMVC/Mybatis(SSM)实现登录功能(带前端)


     🍳作者:天海奈奈

    💭眼过千遍不如手锤一遍:推荐一款模拟面试,斩获大厂 o f f e r ,程序员的必备刷题平台 − − 牛客网 

    👉🏻点击开始刷题之旅

    目录

    前言 

    项目演示

    1 创建工程,完成配置

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

    3 实体类

    4 mapper 

    5 service

    Impl 实现类

    异常

     6 controller

    7 工具类

    MD5

    统一返回对象

    8 前端页面

    总结 


     

    前言 

    开学学校开始讲servlet 后期要求做一个登录功能,这个使用SSM先只做个简单的只带登录功能的,且项目使用了MyBatis-Plus来简化开发流程。看情况决定要不要升级功能或者换个写法。

    项目演示

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

    6933483ac92b4f5da15d124034a0450b.gif

     

    1 创建工程,完成配置

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

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

    06ec12c578f24ddaab9354e681fc860a.png

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

    5af8cb69e6e245e6a036156738e86315.png

    下面Web资源目录也改一下

    f4bb2301b4cb49ef96f6587678510900.png

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

    119b4c0adbe64100a3287668219417d2.png

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

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

    e857e05f83c14585859476dd603419d9.png

     

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

    ad7d7b9199ee451dbe4891a4d271df7b.png点击加号选择tomcat本地

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

     a6834c558da04fd4902d617ab20d096b.png

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

    932267ddba514a919f0d8d3df549ba8c.png

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

     

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Testtitle>
    6. head>
    7. <body>
    8. <h1> 配置完成,终于可以开始了h1>
    9. body>
    10. html>

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

     

    3d480165476641d1a86391ff914456d6.png

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

     

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

    1. aliyun
    2. aliyun
    3. https://maven.aliyun.com/repository/public
    4. org.springframework
    5. spring-webmvc
    6. 5.3.8
    7. com.fasterxml.jackson.core
    8. jackson-annotations
    9. 2.12.3
    10. com.fasterxml.jackson.core
    11. jackson-core
    12. 2.9.9
    13. com.fasterxml.jackson.core
    14. jackson-databind
    15. 2.9.9
    16. org.springframework
    17. spring-jdbc
    18. 5.3.8
    19. com.baomidou
    20. mybatis-plus
    21. 3.4.3.1
    22. mysql
    23. mysql-connector-java
    24. 8.0.16
    25. com.alibaba
    26. druid
    27. 1.2.6
    28. junit
    29. junit
    30. 4.12
    31. test
    32. org.springframework
    33. spring-test
    34. 5.3.8
    35. javax.servlet
    36. javax.servlet-api
    37. 3.1.0
    38. provided
    39. ch.qos.logback
    40. logback-classic
    41. 1.2.3
    42. commons-codec
    43. commons-codec
    44. 1.15
    45. org.jsoup
    46. jsoup
    47. 1.12.1

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

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:mvc="http://www.springframework.org/schema/mvc"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    6. xmlns:task="http://www.springframework.org/schema/task"
    7. xmlns:tx="http://www.springframework.org/schema/tx"
    8. xsi:schemaLocation="
    9. http://www.springframework.org/schema/beans
    10. http://www.springframework.org/schema/beans/spring-beans.xsd
    11. http://www.springframework.org/schema/context
    12. http://www.springframework.org/schema/context/spring-context.xsd
    13. http://www.springframework.org/schema/task
    14. http://www.springframework.org/schema/task/spring-task.xsd
    15. http://www.springframework.org/schema/mvc
    16. http://www.springframework.org/schema/mvc/spring-mvc.xsd
    17. http://www.springframework.org/schema/tx
    18. http://www.springframework.org/schema/tx/spring-tx.xsd">
    19. <context:component-scan base-package="com.xatu"/>
    20. <mvc:annotation-driven>
    21. <mvc:message-converters>
    22. <bean class="org.springframework.http.converter.StringHttpMessageConverter">
    23. <property name="supportedMediaTypes">
    24. <list>
    25. <value>application/json;charset=utf-8value>
    26. list>
    27. property>
    28. bean>
    29. mvc:message-converters>
    30. mvc:annotation-driven>
    31. <mvc:default-servlet-handler/>
    32. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    33. <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    34. <property name="url" value="jdbc:mysql://localhost:3306/cnpc_comment?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"/>
    35. <property name="username" value="******"/>
    36. <property name="password" value="******"/>
    37. <property name="initialSize" value="5"/>
    38. <property name="maxActive" value="20"/>
    39. bean>
    40. <bean id="sessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    41. <property name="dataSource" ref="dataSource"/>
    42. <property name="mapperLocations" value="classpath:mappers/*.xml"/>
    43. <property name="configLocation" value="classpath:mybatis-config.xml"/>
    44. <property name="plugins">
    45. <array>
    46. <bean class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
    47. <property name="interceptors">
    48. <list>
    49. <bean class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor"/>
    50. list>
    51. property>
    52. bean>
    53. array>
    54. property>
    55. bean>
    56. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    57. <property name="basePackage" value="com.xatu.mapper"/>
    58. bean>
    59. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    60. <property name="dataSource" ref="dataSource"/>
    61. bean>
    62. <tx:annotation-driven transaction-manager="transactionManager"/>
    63. beans>

    mybatis.config

    1. "1.0" encoding="UTF-8" ?>
    2. configuration
    3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
    5. <configuration>
    6. <settings>
    7. <setting name="mapUnderscoreToCamelCase" value="true"/>
    8. settings>
    9. configuration>

    logback.xml

    1. "1.0" encoding="UTF-8"?>
    2. <configuration>
    3. <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    4. <encoder>
    5. <pattern>%d{HH:mm:ss} %-5level [%thread] %logger{30} - %msg%npattern>
    6. <charset>GBKcharset>
    7. encoder>
    8. appender>
    9. <root level="debug">
    10. <appender-ref ref="console"/>
    11. root>
    12. configuration>

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

    1. "1.0" encoding="UTF-8"?>
    2. mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3. <mapper namespace="com.xatu.mapper.">

    基本配置就完成了

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

    ec6275b4e59441eaa4747643933566a5.png

    3 实体类

    1. @TableName("manager")
    2. public class Manager {
    3. @TableId(type = IdType.AUTO)
    4. private Long managerId;
    5. private String username;
    6. private String password;
    7. private Integer salt;
    8. @Override
    9. public String toString() {
    10. return "Manager{" +
    11. "userId=" + managerId +
    12. ", username='" + username + '\'' +
    13. ", password='" + password + '\'' +
    14. ", salt=" + salt +
    15. '}';
    16. }
    17. public Long getUserId() {
    18. return managerId;
    19. }
    20. public void setUserId(Long userId) {
    21. this.managerId = userId;
    22. }
    23. public String getUsername() {
    24. return username;
    25. }
    26. public void setUsername(String username) {
    27. this.username = username;
    28. }
    29. public String getPassword() {
    30. return password;
    31. }
    32. public void setPassword(String password) {
    33. this.password = password;
    34. }
    35. public Integer getSalt() {
    36. return salt;
    37. }
    38. public void setSalt(Integer salt) {
    39. this.salt = salt;
    40. }
    41. }

    4 mapper 

    1. public interface ManagerMapper extends BaseMapper {
    2. }

    5 service

    1. public interface ManagerService {
    2. public Manager checkLogin1(String username, String password);
    3. }

    Impl 实现类

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

    1. @Service
    2. //默认方法不开启事务
    3. @Transactional(propagation = Propagation.NOT_SUPPORTED,readOnly = true)
    4. public class ManagerServiceImpl implements ManagerService {
    5. @Resource
    6. private ManagerMapper managerMapper;
    7. @Transactional(rollbackFor = Exception.class)
    8. @Override
    9. public Manager checkLogin1(String username, String password) {
    10. QueryWrapper wrapper = new QueryWrapper();
    11. wrapper.eq("username", username);
    12. Manager manager = managerMapper.selectOne(wrapper);
    13. if (manager == null) {
    14. throw new MemberException("用户不存在");
    15. }
    16. String md5 = MD5Utils.md5Digest(password, manager.getSalt());
    17. if (!md5.equals(manager.getPassword())) {
    18. throw new MemberException("您输入的密码有误");
    19. }
    20. return manager;
    21. }
    22. }

    异常

    1. public class MemberException extends RuntimeException{
    2. public MemberException(String message){
    3. super(message);
    4. }
    5. }

     6 controller

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

    1. @RestController
    2. @RequestMapping("/api/manager")
    3. public class ManagerController {
    4. @Resource
    5. private ManagerService managerService;
    6. @PostMapping("/check_login1")
    7. public ResponseUtils checkLogin1(String username , String password){
    8. ResponseUtils resp ;
    9. resp = new ResponseUtils();
    10. try {
    11. Manager manager = managerService.checkLogin1(username, password);
    12. manager.setPassword(null);
    13. manager.setSalt(null);
    14. resp = new ResponseUtils().put("manager" , manager);
    15. }catch (Exception e){
    16. e.printStackTrace();
    17. resp = new ResponseUtils(e.getClass().getSimpleName(), e.getMessage());
    18. }
    19. return resp;
    20. }
    21. }

    7 工具类

    MD5

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

    1. public class MD5Utils {
    2. public static String md5Digest(String source ,Integer salt){
    3. char[] ca = source.toCharArray();
    4. for(int i = 0 ; i < ca.length ;i++){
    5. ca[i] = (char) (ca[i] + salt);
    6. }
    7. String target = new String(ca);
    8. String md5 = DigestUtils.md5Hex(target);
    9. return md5;
    10. }
    11. }

    统一返回对象

    1. public class ResponseUtils {
    2. private String code;//服务处处理编码
    3. private String message;//服务器返回消息
    4. private Map data = new LinkedHashMap<>();//服务器返回的数据
    5. //成功
    6. public ResponseUtils(){
    7. this.code = "0";
    8. this.message = "success";
    9. }
    10. //失败,传入编码和消息
    11. public ResponseUtils(String code , String message){
    12. this.code = code;
    13. this.message = message;
    14. }
    15. //给data进行赋值
    16. public ResponseUtils put(String key , Object value){
    17. this.data.put(key, value);
    18. return this;
    19. }
    20. public String getCode() {
    21. return code;
    22. }
    23. public void setCode(String code) {
    24. this.code = code;
    25. }
    26. public String getMessage() {
    27. return message;
    28. }
    29. public void setMessage(String message) {
    30. this.message = message;
    31. }
    32. public Map getData() {
    33. return data;
    34. }
    35. public void setData(Map data) {
    36. this.data = data;
    37. }
    38. }

    整体

    a6c0fc3550e14077a3cec18052e87acd.png

     

    8 前端页面

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

     

    e50a9df1d9564c95917e50e81a48abe3.png

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

    login.html

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>登录title>
    6. <link rel="stylesheet" type="text/css" href="assets/element-plus/index.css">
    7. <script src="/assets/vue/vue.global.js">script>
    8. <script src="/assets/element-plus/index.full.js">script>
    9. <script src="/assets/axios/axios.js">script>
    10. <style>
    11. .login-box {
    12. border: 1px solid #DCDFE6;
    13. width: 350px;
    14. margin: 180px auto;
    15. padding: 35px 35px 15px 35px;
    16. border-radius: 5px;
    17. -webkit-border-radius: 5px;
    18. -moz-border-radius: 5px;
    19. box-shadow: 0 0 25px #909399;
    20. }
    21. .login-title{
    22. text-align: center;
    23. margin: 0 auto 40px auto;
    24. color: #303133;
    25. }
    26. style>
    27. head>
    28. <body>
    29. <div id="app">
    30. <el-form ref="loginForm" label-width="80px" :rules="rules" :model="form" class="login-box">
    31. <h2 class="login-title">登录h2>
    32. <el-form-item label="账号" prop="username">
    33. <el-input type="text" placeholder="请输入账号" v-model="form.username">el-input>
    34. el-form-item>
    35. <el-form-item label="密码" prop="password">
    36. <el-input type="password" placeholder="请输入密码" v-model="form.password">el-input>
    37. el-form-item>
    38. <el-form-item>
    39. <el-button type="primary" v-on:click="onSubmit('loginForm')" style="width:200px">登录el-button>
    40. el-form-item>
    41. <el-form-item>
    42. <el-button type="primary" v-on:click="returnBack" style="width:200px">退出el-button>
    43. el-form-item>
    44. el-form>
    45. div>
    46. <script>
    47. const Main = {
    48. data() {
    49. return {
    50. form: {
    51. username: ''
    52. ,password: ''
    53. }
    54. ,rules:{
    55. username: [
    56. {required: true,message : '账号不能为空' , trigger:'blur'}
    57. ],
    58. password:[
    59. {required: true,message : '密码不能为空' , trigger:'blur'}
    60. ]
    61. }
    62. }
    63. }
    64. ,methods : {
    65. onSubmit(formName){
    66. const objApp = this;
    67. const form = this.$refs[formName];
    68. form.validate((valid) => {
    69. if(valid){
    70. console.info("表单校验成功,准备提交数据");
    71. const form = this.form;
    72. const $message = this.$message;
    73. const params = new URLSearchParams();
    74. params.append("username", form.username);
    75. params.append("password", form.password);
    76. axios.post("/api/manager/check_login1", params)
    77. .then(function (response) {
    78. console.info(response);
    79. const json = response.data;
    80. if(json.code=="0"){
    81. window.location.href = "/index1.html";
    82. }else{
    83. $message.error({message:json.message, offset: 100});
    84. }
    85. });
    86. }
    87. })
    88. }
    89. ,returnBack : function (){
    90. window.location.href = "/index.html";
    91. }
    92. }
    93. };
    94. //初始化Vue,绑定Main中的数据,利用ElementPlus对#app容器进行重新渲染
    95. const app = Vue.createApp(Main);
    96. app.use(ElementPlus);
    97. app.mount("#app");
    98. script>
    99. body>
    100. html>

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

    总结 

    这算是完成了基础的登录功能,虽然我们并没有涉及到使用到session去保存用户信息以及去进行权限的判定,但是这个项目算是已经为后续的工作完成了基础的搭建后面只要在库中新建表或者在manager表上进行扩充,改写实体类并进行设计就可以添加更多的功能,这个前端登录页面也可以作为一个通用化的页面,只需要改变里面的的api接口就能做到重复使用。

     

     

  • 相关阅读:
    [附源码]Python计算机毕业设计Django框架的资产管理系统设计与实现
    java毕业设计景区管理系统mybatis+源码+调试部署+系统+数据库+lw
    《JavaEE初阶》文件IO操作
    函数习题(下)
    uniapp 小程序 父组件调用子组件方法
    JDK对String操作优化
    【无标题】
    2022年广西壮族自治区中职网络安全技能竞赛“Linux操作系统渗透测试详解”
    golang设计模式——组合模式
    Mysql的SQL调优-面试
  • 原文地址:https://blog.csdn.net/weixin_57169969/article/details/126817509