Java大作业【即时聊天Java版】有一个需求如下
用户登录及登录验证:用户能够使用固定帐号(帐号程序内置即可,无需完成额外的注册功能)登录系统,系统能对预定的帐号、密码进行验证。
登录功能是大部分系统的入口
- 后台管理系统
- 社交软件
- 电商平台
- 各大邮箱
登录的目的一来是为了识别每一个用户,搭建系统的用户体系;二来是登录了之后方便维护登录态,实现用户相关业务。
所以这也是很多人学习web开发的第一道坎,实现一个简单的登录功能。因此这篇文章就从零开始,使用SpringBoot+Mybatis
实现一个简单的登录功能。(账号程序内置,本篇文章不涉及到注册功能,大家可以自行去实现)
该项目代码已提交到Gitee仓库,仓库地址:https://gitee.com/smietao/GDUT_2020_JavaBigWork。
欢迎clone
和fork
,觉得对你们有所帮助的,可以点个star
。项目会不断更新直至 Java大作业 deadline —— 6月22日。
一、前置条件
- 登录账号使用
MYSQL
数据库存储,因此需要在本机搭建MYSQL
环境或是使用云数据库。 - 使用Java框架
SpringBoot+Mybatis
开发,因此需要配置Maven
环境方便拉jar包。没配置过Maven
的可以参考我的另外一篇博客:初学者必备——win10搭建Java后台开发环境大集合 - 集成开发环境使用IDEA,IDEA需要安装插件
lombok
。(不知道lombok是什么的可以自行百度) - 需要具备一定的Javaweb开发知识,理解MVC架构。
- 会基础的
HTML+CSS+JS
前端相关知识
二、创建工程
打开IDEA,在编辑器左上角选择File -> New -> Project
选择Spring Initializr创建Spring Boot工程,这里选择的是
Default
,因此需要联网才能Next填写POM相关配置
勾选依赖。勾选了的依赖会默认写入
pom.xml
,不需要我们再次去导入- Spring Boot DevTools:提供热更新功能
- lombok:@Data注解快捷生成Get\Set方法
- Spring Web:快速构建Web应用
- Thymeleaf:
Spring Boot
官方推荐的模板引擎,类似于jsp - Spring Data JDBC:
Java
代码连接MYSQL
- Mybatis Framework:
Mybatis
轻量级持久层框架
输入工程名以及工程的本地路径,这里根据自己的情况以及老师要求填写即可
三、Maven
工程创建完成后,如果之前没有使用过Maven,则Maven会根据pom.xml
去远程仓库拉取jar包,不过IDEA内置的Maven是去国外中央仓库下载的,会比较慢。可以根据上文的链接配置好Maven,之后在IDEA中选择自己本地的Maven进行后续操作。
File -> settings -> 搜索框输入maven
点击OK,之后IDEA会根据新的Maven配置重新下载jar包,这时候如果右下角弹窗则选择
auto import
——当pom.xml
中有修改会自动更新
四、后端项目架构
这是使用的是Javaweb
经典的MVC三层架构,即Model、view、controller。工程结构如图:
新建的项目是没有这些包和文件夹的,需要自己一点点搭建起来
4.1 SpringBoot配置文件
- 点开
resourcs
文件夹,可以看到application.properties
。这是Spring Boot默认的配置文件。这里我的习惯是使用yml
格式的,因此将其修改为application.yml
,并写入以下代码
server:port:8081spring:devtools:restart:enabled:falsedatasource:url: jdbc:mysql://your ip address:端口号/数据库名?useUnicode=true&serverTimezone=GMT%2B8username: smietaopassword: xxxxxxxmybatis:type-aliases-package: com.smietao.instantchatmapper-locations: classpath*:mapper/*.xmlcheck-config-location:trueconfiguration:# 开启二级缓存cache-enabled:truelog-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case:truemapper:mappers:- com.smietao.instantchat.base.BaseMapperWeiLT- tk.mybatis.mapper.common.Mappernot-empty:trueidentity: mysql
这里配置的有五点
- 端口号port:可修改,默认为8080
- devtools:热更新功能
- datasource:
MySQL
数据源配置(这个很重要) - Mybatis:配置类别名所在包、mapper文件所在位置、开启日志以及二级缓存
- mapper:通用mapper配置
4.2 配置web相关
- 在resouces目录下创建
static
目录,用于存放静态资源文件,例如css、font、img、js - 在resouces目录下创建
templates
目录,用于存放动态页面,例如html、ftl - 在网上找一个登录界面模板,修改名为
index.html
,即项目首页。放入templates。打开Application
类,运行main方法,启动项目,在浏览器输入localhost:8081
看看能否访问
4.3 搭建MVC三层架构
在src/main/java目录下创建
- controller:控制层,与页面交互
- service:服务层,编写业务代码
- model:模型层,映射数据库
- mapper:存放操作数据库的mapper接口类以及xml文件
4.3.1 编写model
@Data@Table(name="we_user")publicclassUserWeiLT{@Id@Column(name="id")public Integer id;@Column(name="email")public String email;@Column(name="password")public String password;@Column(name="username")public String username;@Column(name="create_time")private Date createTime;@Column(name="update_time")private Date updateTime;}
该类是与数据库表映射的实体类,即类中的每一个属性对应数据库表的每一个字段;@Data是lombok
的注解,用于快速生成get\set
方法;@Table和@Column是通用Mapper的注解。至于通用Ma
pper是什么、怎么使用,不是本文的重点,大家可以自行百度学习使用。而且这里也可以不使用通用Mapper,直接在mapper.xml
文件写sql语句。
4.3.2 编写Mapper
mapper是Mybatis
框架操作数据库的方式,通过xxxMapper
中定义的接口方法,在底层根据xml文件自动生成实现方法,供我们使用。
@Mapper@RepositorypublicinterfaceUserMapperWeiLTextendsBaseMapperWeiLT<UserWeiLT,String>{}
这里的UserMapper
没有任何的抽象方法是因为其继承了BaseMapper
,其中封装了对单表的基础操作,一般业务我们使用这些就足够了。对通用Mapper不熟悉的同学我还是建议去网上找资料学习一下如何使用。
- @Mapper:标识这是一个Mapper类
- @Repository:效果等同于@Component,将该类交给
Spring IOC
管理,Repository
标识这是Model(Dao)
层的一个类
当然这里不使用通用Mapper而是用Mybatis
的基本写法——xml文件中写sql语句,也是同理的,大家实现的时候可以多多尝试。
4.3.3 编写Service
Service层在MVC三层架构中是负责实现业务的,所以根据规范我们的业务代码也是写在此处。
就拿登录注册来说,其中的业务便是检测——
- 账号是否存在
- 账号存在的情况下,密码是否正确
以上两点判断都应该在Service层调用Dao层方法来实现,并将结果传递给Controller层。
Service层根据规范需要定义接口,方便我们调用的时候能在上层方法看到如何入参、回参的含义以及方法的作用。
interface
接口定义
publicinterfaceUserServiceWeiLTextendsBaseServiceWeiLT<UserWeiLT,String>{/**
* 检查用户输入的邮箱和密码是否正确
* @param loginDTOWeiLT 邮箱、密码 DTO类
* @return 1表示成功,-1表示邮箱账号不存在,-2表示密码不匹配
*/intcheckUserLogin(LoginDTOWeiLT loginDTOWeiLT);}
Impl
类实现
@ServicepublicclassUserServiceImplWeiLTextendsBaseServiceImplWeiLT<UserWeiLT, String>implementsUserServiceWeiLT{@Autowiredprivate UserMapperWeiLT userMapperWeiLT;@Overridepublic BaseMapperWeiLT<UserWeiLT, String>getMappser(){return userMapperWeiLT;}@OverridepublicintcheckUserLogin(LoginDTOWeiLT loginDTOWeiLT){
Example example=newExample(UserWeiLT.class);
example.and().andEqualTo("email",loginDTOWeiLT.getEmail());
UserWeiLT user= userMapperWeiLT.selectOneByExample(example);if(user== null){// 如果查询不出数据,说明账号不存在return-1;}else{// 数据库中的密码
String password= user.getPassword();// 用户输入的密码
String inputPassword= loginDTOWeiLT.getPassword();if(!password.equals(inputPassword)){// 如果密码不匹配return-2;}else{return1;}}}}
- @Service注解:其作用于上文讲的@Repository同理,这里不再赘述
- @Autowired注解:注入上文的
UserMapper
类,即依赖注入,在方法中可以直接调用该类的方法而不需要new一个新的对象 - 因为该类继承
BaseServiceImplWeiLT
,所以必须覆写getMappser()
方法,该方法需要返回一个Mapper
对象,用于通用Service操作数据库 checkUserLogin()
方法中的Example是通用Mapper的写法,用于拼接sql查询条件,已实现自己预期的业务- int返回值是为了便于controller层中的接口判断业务情况,返回数据或提示信息
4.3.4 编写Controller
Controller层是控制层,与页面进行交互数据。在这里先编写一个接口,用于登录表单的提交。
/**
* @author smietao
* 登录系统
*/@ControllerpublicclassLoginControllerWeiLT{@Autowiredprivate UserServiceWeiLT userService;@GetMapping(value="")public StringloginInit(){returnautoLogin();}@GetMapping(value="/login")public StringautoLogin(){return"login";}@PostMapping("/weLogin")public StringweLogin(Model model,LoginDTOWeiLT loginDTOWeiLT){int res= userService.checkUserLogin(loginDTOWeiLT);
String msg="";if(res==-1){// 邮箱账号不存在
msg="邮箱账号不存在,请重新输入";}elseif(res==-2){// 密码错误
msg="密码错误,请重新输入";}if(res==-1|| res==-2){// 如果是错误的登录
model.addAttribute("message", msg);return"login";}// 通过验证,登录成功return"success";}}
- 类上的@Controller注解的作用是声明该类是
controller
层的类,同时将该类交给Spring IOC管理。 - 类中的
loginInit()
是为了访问项目localhost:8081
能跳转到登录页。而weLogin()
方法则是登录页用户输入账号密码后向后端服务器请求的方法。
weLogin()
方法解析:
@PostMapping
是Servlet mapping
请求路径映射,Post
表示客户端必须以post
方式发起请求,发起请求的路径就是该注解的值方法返回String类型是
SpringMVC
的视图解析器写法,这里returntemplates
下的页面文件名即可跳转至该页面model.addAttribute()
方法可以将后端的数据封装进域对象,便于在页面中展示数据或是提示信息
至此,后端的代码已经over了,剩下的就是前端代码的小改了。
五、前端页面编写
5.1 首页代码
这里的首页只是一个登录窗口,因此大家可以在网络社区上找一个自己觉得养眼的登录模板(很多的),拿来就用(疯狂白嫖)。
这里就不贴我的登录代码了,挑一些重要的讲。
<form>
表单的action
属性配置后端接口请求路径
<formmethod="post"action="/weLogin"class="login100-form validate-form layui-form">
- 引入外链
css、js
使用绝对路径@{}的方式,如此后台使用请求转发的方式跳转页面后就不会因为使用了相对路径,导致引用路径的改变而丢失样式。
<scripttype="text/javascript"th:src="@{/js/layui/layui.all.js}"></script>
- 登录操作一般需要在前端用js进行一些校验
<script th:inline="javascript">var layer;$(function(){
layui.use(['form','layer'],function(){var form= layui.form;
form.verify({
email:function(value){if(value.trim()==''){return'邮箱不能为空';}if(value!=""){if(!/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test(value)){return"邮箱格式不正确";}}}, password:function(v){if(v.trim()==''){return"密码不能为空";}}});
form.render();});
layer= layui.layer;var msg=[[${message}]];// var msg = '${message}';if(msg.trim()!=""){
layer.msg(msg,{icon:5, anim:6, offset:'t'});}});if(window!= top)
top.location.href= location.href;</script>
[[${message}]]
是从后端拿到controller
在model中设置的message值,用于登录业务的错误信息提示弹窗。(邮箱不存在、密码错误)
5.2 登录成功页面
可以简单创建一个登录成功的html页面,用于测试登录成功后的跳转功能,在此基础上继续开发后续的业务。
<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><title>WeTalk聊天室</title></head><body><h1style="color: red">恭喜你登录成功WeTalk系统</h1></body></html>
六、后续/总结
逐步完成上述的所有内容,一个简单的登录功能(带数据库)就实现成功了。其中涉及到的知识点有
- Maven
- SSM
- 通用Mapper
SpringBoot
自动配置\配置文件html、css、js
前端三件套- 模板引擎
如果光是使用而不深究其原理的话,这些东西其实并不多,也不复杂。(这也框架的好处)因此希望大家能亲手去实践一下,如果是第一次做这类程序的话,会很有体验\收获的。
你会发现,写代码不仅仅是完成老师的作业,更奇妙的是经你之手敲出来的代码,真正地实现了一个日常使用的功能之时,你会找回在学习第一门编程语言,对着电脑屏幕以及教学课本,一个字母一个字母地把Hello World!
的 demo示例代码敲在编译器上并运行时内心的喜悦。这看似微不足道的入门程序,却是你开启编程世界的敲门砖、垫脚石。奔涌吧后浪~
在我小的时候,总以为这个世界很单纯。没有赢不了的比赛,努力付出就会有所回报,一切皆有可能…