一、前端环境搭建
在前端框架vue-element-admin
这个项目中,有一个简洁轻量型的项目vue-admin-template
,这里面初始化的内容少,适合初学者,防止一上来就被那么多的代码弄晕。
快速安装
# 克隆项目 git clone https://github.com/PanJiaChen/vue-admin-template.git # 进入项目目录 cd vue-element-admin # 安装依赖 npm install # 可以通过如下操作解决 npm 下载速度慢的问题 npm install --registry=https://registry.npm.taobao.org # 本地开发 启动项目 npm run dev
2 个npm install
的任意选择一个即可,下面的使用的是国内的淘宝镜像,速度会更快些。
启动之后就会看到登录页,说明安装成功。
点击登录进去,就可以看到首页了。
但是我们还没实现后端,怎么就登录了?这是因为前端框架里目前的请求都是走的它内置的 mock,所以等会要去开发后端接口替换掉这些 mock。
二、后端环境搭建
创建应用
直接使用 idea 创建一个 springboot 应用即可,可以使用Spring Initializr
来快速创建。
完事之后就要在pom.xml
里添加响应依赖即可。
我这里是创建的时候勾选了一些项目,自动会生成出来依赖。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>org.springframework.experimental</groupId> <artifactId>spring-native</artifactId> <version>${spring-native.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-core</artifactId> <version>3.0.5</version> </dependency> </dependencies>
重点是mybatis-plus-core
这个依赖要添加好,后面要用它进行数据库交互。
配置 application.properties
这里目前主要配置数据库的连接信息。我的mysql安装在华为云上,系统是 centos8。
# mysql spring.datasource.url=jdbc:mysql://xxx.x.xx.101:3306/bloomtest?characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=xxxxxx spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.hikari.max-lifetime=1000000 # 上下文地址为 server.servlet.context-path=/bloomtest
spring.datasource.hikari.max-lifetime
:默认数据源连接池,连接最大存活时间,设置长一些,防止长时间不操作断开连接,不方便调试。
server.servlet.context-path
:配置上下文路径,比如我的登录接口路径为/user/login
,请访问的时候就是localhost:8080/bloomtest/user/login
。
三、实现登录
登录就涉及到用户,还会涉及到权限管理之类,但是这个不作为当前的重点,目前只是需要可以正常登录即可。
F12 可以查看 mock 登录时候的请求,共有 2 个接口,所以就参照 mock 返回的数据来返回对应真实的数据。
代码目前大致有如下的结构,先眼熟即可。
1. mysql 建表
登录的话,就是拿前端传参过来的用户名和密码,看下是否存在数据库用户表里,存在就可以登录,不存在就返回失败。
所以,在此之前还需要建张 user 表:
CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `username` varchar(30) DEFAULT NULL COMMENT '用户名', `password` varchar(30) DEFAULT NULL COMMENT '年龄', `createTime` datetime NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '创建时间', `updateTime` datetime NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='用户表';
然后手动新增了 3 个用户:
2. 后端-实现 /login 接口
(1)创建实体类 User
package com.pingguo.bloomtest.pojo; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import java.util.Date; @Data public class User { @TableId(type = IdType.ID_WORKER) private Long id; private String username; private String password; @TableField(fill = FieldFill.INSERT) // 新增的时候填充数据 private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) // 新增或修改的时候填充数据 private Date updateTime; }
注解神马的在之前 spring 相关技术栈里已经有过介绍,有需要的可以去翻看或者直接百度即可。
(2)创建接口 UserDAO
package com.pingguo.bloomtest.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.pingguo.bloomtest.pojo.User; import org.springframework.stereotype.Repository; @Repository public interface UserDAO extends BaseMapper<User> { }
这里使用 mybatis-plus 框架,在文末会附上之前学习此框架的内容供学习参考。
(3)创建Service层 UserService
这里就是真正处理业务逻辑的地方,这里提供方法直接给后面的 controller 层调用。
package com.pingguo.bloomtest.service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.pingguo.bloomtest.dao.UserDAO; import com.pingguo.bloomtest.pojo.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; @Service public class UserService { @Autowired private UserDAO userDAO; /** * 判断用户是否存在,存在则返回true,不存在则返回false * @param username 用户名 * @param password 用户密码 * @return true,false */ public boolean isUserExist(String username, String password) { //创建对象,泛型里加上实体对象 QueryWrapper<User> wrapperUser = new QueryWrapper<>(); // 先创建一个 hashmap,然后把多个条件put进去,再调用allEq Map<String, Object> map = new HashMap<>(); map.put("username", username); map.put("password", password); // 设置查询的条件 wrapperUser.allEq(map); // 调用方法查询一个返回记录 int count = userDAO.selectCount(wrapperUser); if (count == 1) { return true; } else { return false; } } }
这里就与 mysql 进行交互了,用到的就是 mybatis-plus 的语法,详见文末附上的文章链接。
这里方法返回 true 表示库里存在该用户,即可以登录。否则返回 false。
(4)创建Controller层 UserController
这里就是接收前端请求的地方了。
package com.pingguo.bloomtest.controller; import com.pingguo.bloomtest.common.Result; import com.pingguo.bloomtest.controller.request.UserRequest; import com.pingguo.bloomtest.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("user") public class UserController { @Autowired UserService userService; @PostMapping("/login") public Result login(@RequestBody UserRequest user) throws Exception { String username = user.getUsername(); String password = user.getPassword(); if (userService.isUserExist(username, password)) { Map<String, Object> userToken = new HashMap<>(4); userToken.put("token","admin-token"); return Result.success(userToken); } else { return Result.fail("用户名或密码错误"); } } }
Controller 层调用 Service层,Service层 再调用 dao 层与 DB进行交互。
这里返回了是一个Result
类型的结果,这里是为了更好的返回数据,进行了一个类的封装。
在 common 包下新建了一个类Result
:
package com.pingguo.bloomtest.common; import lombok.Data; @Data public class Result { private static final int SUCCESS_CODE = 20000; private static final int FAIL_CODE = 20005; private int code; private String message; private Object data; private Result(int code, String message, Object data) { this.code = code; this.message = message; this.data = data; } public static Result success() { return new Result(SUCCESS_CODE, "成功", null); } public static Result success(Object data) { return new Result(SUCCESS_CODE, "成功", data); } public static Result fail(String message) { return new Result(FAIL_CODE, message, null); } /** * 传入失败状态码,返回Result结果 * @param code 失败状态码 * @param message 文本提示 * @return Result结果 */ public static Result fail(int code, String message) { return new Result(code, message, null); } }
另外,这里的传参UserRequest user
,也是为了便于获取请求参数,而创建的类。
(4)启动应用,测试 /login 接口
直接使用 postman 进行调用。
换个不存在的传参。
接口正常。
3. 前端-修改代码实现登录
(1)修改 .env.development
这样前端请求访问的就是后端的http://127.0.0.1:8080
地址和端口。
(2)修改 \src\api\user.js
这里就是前端请求的接口路径,替换成我们实现的 /login,
(3)\src\utils\request.js
至于我后端接口返回成功code 为什么是 20000呢?是因为前端框架里做了统一的封装,这里喜欢的话你自己也可以改成别的。
(4)\src\views\login\index.vue
这里就是存放页面的地方了,是后面前端代码的主要阵地。
从Login
按钮的绑定的事件知道handleLogin
就是用来处理登录的方法,不过这里暂时不需要进行改动。
重新构建后点击登录,可以看到请求了真正的后端接口。
可是报错了。
4. 解决跨域
报错是跨域问题,解决跨域,可以在后端进行处理,增加一个配置类。
package com.pingguo.bloomtest.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); return new CorsFilter(source); } private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); // 1允许任何域名使用 corsConfiguration.addAllowedOrigin("*"); // 2允许任何头 corsConfiguration.addAllowedHeader("*"); // 3允许任何方法(post、get等) corsConfiguration.addAllowedMethod("*"); return corsConfiguration; } }
重试一下,登录请求成功了,但是不能跳转,因为还有个接口没实现,那就是/useInfo
。
5. 后端-实现 /useInfo 接口
套路跟上面一样,但是这里因为直接写一个与 mock 返回的一样的数据,所以直接在 controller 类下新增一个控制器方法直接处理返回。
@GetMapping("/useInfo") public Result useInfo(HttpServletRequest request) throws Exception { String token = request.getParameter("token"); Map<String, Object> result = new HashMap<>(8); ArrayList roles = new ArrayList<>(); String allowableToken = "admin-token"; if (token.equals(allowableToken)) { roles.add("admin"); result.put("roles", roles); result.put("introduction", "我是超级管理员"); result.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"); } return Result.success(result); }
重启应用,可以正常登录。
6. 后端-实现 /logout 接口
最后再补充一个退出登录的接口。
@PostMapping("/logout") public Result logout() throws Exception { return Result.success(); }
重启测试,点击头像悬浮展示的logout,成功退出到登录页。
四、小结
本篇内容主要是前后环境调通,以及基础登录的实现,后续就可以正常先进行重要功能的开发了。
附上之前整理的 mybatis-plus 的学习笔记,简单明了易上手,仅供参考。