从头开始,基于springboot的web登录详细登录实现。

从头开始,基于springboot的web登录详细登录实现。

创建springboot项目

工欲善其事,必先利其器。下面就和我一起轻扣IDEA的大门,新建一个springboot项目。

  1. 打开IDEA,点击file—new—project开始创建一个新项目。
    在这里插入图片描述
  2. 选择spring Initializr,然后默认选项next
    在这里插入图片描述
  3. 按图填写自己的项目信息然后next
    在这里插入图片描述
  4. 选择spring web 然后next
    在这里插入图片描述
  5. 选择项目存放路径,然后点击 Finish。等待片刻
    在这里插入图片描述
  6. 等待IDEA构建好项目后,项目结构如下图所示。
    在这里插入图片描述

web项目功能集成

  1. 配置项端口8088

     在application.properties文件中添加server.port=8088
    

在这里插入图片描述
注意:如果pom文件没有项目打包方式会导致修改端口无效。在pom文件中加入jar就可以解决。
在这里插入图片描述
2. 集成lombox
2.1 在pom文件中添加jar包

 <!--集成lombox-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

2.2 安装lombox插件
在这里插入图片描述
2.3 使用lombox编写User类。

package com.yangpeng.logindemo.models;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.io.Serializable;
import java.util.Date;

@Getter
@Setter
@ToString
public class User implements Serializable {
    private static final long serialVersionUID = 68403886070098162L;
    private Integer uid;
    private String userName;
    private String passWord;
    private String realName;
    private Date updateTime;
}
  1. 集成Thymeleaf模板引擎
    3.1 在pom文件中添加jar包
<!--集成Thymeleaf模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

3.2 在application.properties文件中加入配置

# thymeleaf
#视图存放的位置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.check-template-location=true
#网页的后缀名
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=utf-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.cache=false

3.3创建测试类

@Controller
@RequestMapping("/test")
public class TestController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/user")
    public String getUser(Model model) {
        User user = new User();
        user.setUid(1);
        user.setUserName("yangpeng");
        user.setRealName("杨朋");
        user.setUpdateTime(new Date());
        model.addAttribute("user", user);
        return "userInfo";
    }
  }

3.4 创建页面userInfo

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form>

    <input type="text" hidden="hidden" th:field="${user.uid}" />
    <textarea th:field="${user.userName}"></textarea>
    <textarea th:field="${user.passWord}"></textarea>
    <textarea th:field="${user.realName}"></textarea>
    <textarea th:field="${user.updateTime}"></textarea>
</form>
</body>
</html>

3.5页面模板引擎集成完成,效果如下
在这里插入图片描述
4. 集成MySQL+mybatis
4.1 添加mysql和mybatis依赖的jar包

  <!--集成mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!--集成mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

4.2 添加mysql配置

#MySQL数据库的简单设置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/login?Unicode=true&characterEncoding=utf-8&useAffectedRows=true&serverTimezone=GMT&allowMultiQueries=true
spring.datasource.username=yangpeng
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#设置等待数据库的最大连接数量,0表示没有限制
spring.datasource.tomcat.max-idle=10
#设置连接数据库最大活动数量
spring.datasoure.tomcat.max-active=100
#设置最大的等待毫秒数,超出报错
spring.datasoure.tomcat-wait=10000
#设置数据库连接初始化的连接池数量
spring.datasource.tomcat.initial-size=5

4.3添加mybatis配置

#配置映射文件存放位置
mybatis.mapper-locations=classpath:mapper/*.xml
#扫描别名
mybatis.type-aliases-package=com.yangpeng.logindemo.models
#打开二级缓存,默认一级缓存是打开的
mybatis.configuration.cache-enabled=true

4.4写一个测试用例
4.4.1 编写dao

package com.yangpeng.logindemo.dao;


import com.yangpeng.logindemo.models.User;
import org.apache.ibatis.annotations.Mapper;


@Mapper
public interface UserDao {

    User getUserByUid(Integer uid);

    int insert(User user);

    User getUserByUserName(String userName);
}

4.4.2编写dao对应的mapper

<?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.yangpeng.logindemo.dao.UserDao">

    <resultMap id="BaseResultMap" type="com.yangpeng.logindemo.models.User">
        <result column="id" jdbcType="INTEGER" property="uid" />
        <result column="userName" jdbcType="VARCHAR" property="userName" />
        <result column="passWord" jdbcType="VARCHAR" property="passWord" />
        <result column="realName" jdbcType="VARCHAR" property="realName" />
        <result column="updateTime" jdbcType="TIMESTAMP" property="updateTime" />
    </resultMap>

    <select id="getUserByUid" resultMap="BaseResultMap">
        select * from t_sys_user where id = #{uid}
    </select>

    <insert id="insert" useGeneratedKeys="true" keyProperty="uid" parameterType="com.yangpeng.logindemo.models.User">
        insert into t_sys_user(userName,passWord,realName,updateTime)
        values(#{userName},#{passWord},#{realName},#{updateTime})
    </insert>

    <select id="getUserByUserName" resultMap="BaseResultMap">
        select * from t_sys_user where userName = #{userName} LIMIT 1
    </select>

</mapper>

4.4.3 编辑service

package com.yangpeng.logindemo.service;

import com.yangpeng.logindemo.models.User;

public interface IUserService {

    User getUserByUid(Integer uid);

    User insert(User user);

    User getUserByUserName(String userName);
}

package com.yangpeng.logindemo.service.impl;

import com.yangpeng.logindemo.dao.UserDao;
import com.yangpeng.logindemo.models.User;
import com.yangpeng.logindemo.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private UserDao userDao;

    @Override
    public User getUserByUid(Integer uid) {
        try {
            return userDao.getUserByUid(uid);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }

    }

    @Override
    public User insert(User user) {
        try {
            user.setUpdateTime(new Date());
            int result = userDao.insert(user);
            if (result == 1) {
                return user;
            } else {
                return null;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }

    @Override
    public User getUserByUserName(String userName) {
        try {
            return userDao.getUserByUserName(userName);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }

    }
}

4.4.4编辑controller

package com.yangpeng.logindemo.controller;


import com.yangpeng.logindemo.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
@RequestMapping("/test")
public class TestController {

    @Autowired
    private IUserService userService;
    
    @RequestMapping("/userInfo")
    public String userInfo(Integer uid,Model model) {
        model.addAttribute("user", userService.getUserByUid(uid));
        return "userInfo";
    }

}

4.4.5 整个代码目录如下
在这里插入图片描述
5. 集成redis
5.1 pom文件添加redis需要的依赖jar包

<!--集成redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

5.2 配置文件添加redis 配置

#Redis数据库的简单设置
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码(默认为空)
spring.redis.password=123456
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000

5.3 编写RedisUtils工具类

package com.yangpeng.logindemo.utils;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

@Service
public class RedisUtils {

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 写入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 写入缓存设置时效时间
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime ,TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 批量删除对应的value
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }
    /**
     * 批量删除key
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0){
            redisTemplate.delete(keys);
        }
    }
    /**
     * 删除对应的value
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    /**
     * 判断缓存中是否有对应的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    /**
     * 读取缓存
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }
    /**
     * 哈希 添加
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
    }
    /**
     * 哈希获取数据
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey){
        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
        return hash.get(key,hashKey);
    }
    /**
     * 列表添加
     * @param k
     * @param v
     */
    public void lPush(String k,Object v){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k,v);
    }
    /**
     * 列表获取
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k,l,l1);
    }
    /**
     * 集合添加
     * @param key
     * @param value
     */
    public void add(String key,Object value){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key,value);
    }
    /**
     * 集合获取
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }
    /**
     * 有序集合添加
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key,Object value,double scoure){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key,value,scoure);
    }
    /**
     * 有序集合获取
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key,double scoure,double scoure1){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}

总结:至此已经准备好了做web登录的准备工作。

web登录功能

  1. 编写登录页面和登录成功页面
    1.1 登录页面login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>请登录</title>
</head>
<body>
<form method="post" th:action="@{/login}">
    <table>
        <tr>
            <td>提示信息:</td>
            <td><input type="text" th:value="${msg}" readonly="readonly"/></td>
        </tr>
        <tr>
            <td>用户名:</td>
            <td><input type="text" name="userName" /></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input type="text" name="passWord" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="提交" />
            </td>
        </tr>
    </table>
</form>
</body>
</html>

1.2 登录成功页面index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录成功</title>
</head>
<body>
<form>
    <table>
        <tr>
            <td>登录成功</td>
        </tr>
    </table>
</form>
</body>
</html>
  1. 登录方法和登录成功方法
package com.yangpeng.logindemo.controller;

import com.yangpeng.logindemo.models.User;
import com.yangpeng.logindemo.service.IUserService;
import com.yangpeng.logindemo.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

@Controller
public class LoginController {

    @Autowired
    private IUserService userService;

    @Autowired
    private RedisUtils redisUtils;

    public final static Long expireTime = 30L;

    /**
     * 首页
     * @param model
     * @return
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model) {
        return "index";
    }

    /**
     * 登录方法
     * @param request
     * @param model
     * @param attributes
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(HttpServletRequest request, Model model, RedirectAttributes attributes) {
        HttpSession sessoin = request.getSession();
        String userName = request.getParameter("userName");
        String passWord = request.getParameter("passWord");
        Object token = sessoin.getAttribute("token");
        Object username = sessoin.getAttribute("username");
        Object redisToken = null;
        if (username != null) {
            redisToken = redisUtils.get(username.toString());
        }
        if (token != null && username != null && redisToken !=null &&
                userName.equals(username.toString()) && token.equals(redisToken)) {
            attributes.addFlashAttribute("msg", "登录成功");
            return "redirect:/index";
        } else {
            User user = userService.getUserByUserName(userName);
            if (user == null) {
                attributes.addFlashAttribute("msg", "用户不存在");
                return "redirect:/login";
            } else {
                if (user.getPassWord() != null && user.getPassWord().equals(passWord)) {
                    boolean isSuccess = redisUtils.set(userName,userName+":"+user.getUid(),expireTime, TimeUnit.MINUTES);
                    if (isSuccess) {
                        sessoin.setAttribute("token", userName + ":" + user.getUid());
                        sessoin.setAttribute("username", userName);
                        attributes.addFlashAttribute("msg", "登录成功");
                        return "redirect:/index";
                    } else {
                        attributes.addFlashAttribute("msg", "登录失败,请联系管理员");
                        return "redirect:/login";
                    }
                } else {
                    attributes.addFlashAttribute("msg", "密码不正确");
                    return "redirect:/login";
                }
            }
        }

    }
}

3 登录拦截器LoginHandlerInterceptor

package com.yangpeng.logindemo.handlerInterceptor;


import com.yangpeng.logindemo.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;


/**
 * 登录拦截器
 */
public class LoginHandlerInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisUtils redisUtils;

    public final static Long expireTime = 30L;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //通过getAttribute获取session的值
        Object username = request.getSession().getAttribute("username");
        Object token = request.getSession().getAttribute("token");
        //校验登录凭证
        if(token !=null && username !=null){
            Object redisToken = redisUtils.get(username.toString());
            if (redisToken != null && token.equals(redisToken)) {
                //校验凭证通过,更新凭证缓冲时间
                redisUtils.set(username.toString(),token,expireTime, TimeUnit.MINUTES);
                //放行
                return true;
            } else {
                //返回到登录页面:
                request.getRequestDispatcher("/login.html").forward(request,response);
                return false;
            }
        }else{
            //返回到登录页面:
            request.getRequestDispatcher("/login.html").forward(request,response);
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

}

4 管控WebMvcConfig

package com.yangpeng.logindemo.config;

import com.yangpeng.logindemo.handlerInterceptor.LoginHandlerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

//继承接口WebMvcConfigurer实现管理SpringMvc
@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    //为了初始化注入redis
    @Bean
    LoginHandlerInterceptor loginHandlerInterceptor() {
        return new LoginHandlerInterceptor();
    }

    //第一种实现方法:编写addViewControllers方法
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //将login.html映射到路径urlpath为:"/"上
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/login.html").setViewName("login");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //排除"/"下的全部路径,除了"/login.html","/","/user/login"
        registry.addInterceptor(loginHandlerInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/login.html","/","/login","/static/**");
    }
    //解决静态资源文件夹被拦截
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }
}

5 测试

5.1登录页
在这里插入图片描述
5.2登录失败
在这里插入图片描述
5.3登录成功
在这里插入图片描述
5.4登录成功后资源访问
在这里插入图片描述

总结

无聊时间写一个简单的登录。不知道实现逻辑是否有问题。如果有请艾特我。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值