首先,可以预览项目工程的开发文件目录
二话不说,直接上代码,
一、Springboot+Vue的登录接口案例
1、编码部分
1.1、准备数据库
CREATE TABLE `sys_user` (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`account` varchar(200) DEFAULT NULL COMMENT '账户',
`user_name` varchar(45) DEFAULT NULL COMMENT '用户名',
`password` varchar(45) DEFAULT NULL COMMENT '用户密码',
`email` varchar(200) DEFAULT NULL COMMENT 'email',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`whether_to_use` tinyint(1) DEFAULT NULL COMMENT '是否在使用\r\n【"0:停止使用\n1:正在使用"】',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
1.2、pom文件引入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>reast.introduce.cn</groupId>
<artifactId>datamask-web001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>datamask-web</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--fastjson依赖,用户一会儿前端传值,转换json数据-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<!--jwt 依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatis-plus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<!-- <scope>provided</scope>-->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
1.3、用户实体类
package reast.introduce.cn.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* 用户实体类
*
*/
@Data
@TableName(value = "sys_User")
public class SysUser implements Serializable {
@TableId(type = IdType.AUTO)
private Integer userId; //用户ID
private String account; //账户
private String userName; //用户名
private String password; //用户密码
private String email; //email
private Timestamp createTime; //创建时间
private Timestamp updateTime; //更新时间
private boolean whetherToUse; //是否在使用【"0:停止使用 1:正在使用"】
}
1.4、跨域配置
package reast.introduce.cn.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;
/**
* @Description 跨域配置
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//允许源,这里允许所有源访问,实际应用会加以限制
corsConfiguration.addAllowedOrigin("*");
//允许所有请求头
corsConfiguration.addAllowedHeader("*");
//允许所有方法
corsConfiguration.addAllowedMethod("*");
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
1.5、web配置
package reast.introduce.cn.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import reast.introduce.cn.interceptor.LoginInterceptor;
/**
*
* @Description: web配置
**/
@Configuration
public class DemoWebConfig implements WebMvcConfigurer {
/**
* 拦截器配置
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/api/**")
//放行路径,可以添加多个
.excludePathPatterns("/api/login");
}
}
1.6、登录用户实体类
package reast.introduce.cn.dto;
import lombok.Data;
@Data
public class LoginDTO {
private String userName; //用户名
private String password; //用户密码
}
1.7、用户登录拦截器
package reast.introduce.cn.interceptor;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.servlet.HandlerInterceptor;
import reast.introduce.cn.result.InfoResult;
import reast.introduce.cn.result.loginResult;
import reast.introduce.cn.util.HttpContextUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Description: 用户登录拦截器
**/
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
//从header中获取token
String token = request.getHeader("token");
//如果token为空
if (StringUtils.isBlank(token)) {
setReturn(response,400,"用户未登录,请先登录","");
return false;
}
//在实际使用中还会:
// 1、校验token是否能够解密出用户信息来获取访问者
// 2、token是否已经过期
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {}
//返回json格式错误信息
private static void setReturn(HttpServletResponse response, Integer code, String msg,String token) throws IOException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtil.getOrigin());
//UTF-8编码
httpResponse.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
loginResult loginResult = new loginResult(code,msg,token);
ObjectMapper objectMapper = new ObjectMapper();
String json0 = objectMapper.writeValueAsString(loginResult);
httpResponse.getWriter().print(json0);
}
}
1.8、用户接口
【主要用来取代sql,不需要写xml】
package reast.introduce.cn.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import reast.introduce.cn.bean.SysUser;
public interface SysUserMapper extends BaseMapper<SysUser> {
}
1.9、返回响应类
package reast.introduce.cn.result;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class loginResult {
//相应码
private Integer code;
//信息
private String message;
//返回数据
private String token;
}
1.10、service层
package reast.introduce.cn.service;
import reast.introduce.cn.dto.LoginDTO;
import reast.introduce.cn.result.InfoResult;
import reast.introduce.cn.result.loginResult;
public interface InfoService {
public loginResult userlogin(LoginDTO loginDTO);
}
1.11、service的实现类
主要写业务代码
package reast.introduce.cn.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import reast.introduce.cn.bean.SysUser;
import reast.introduce.cn.dto.LoginDTO;
import reast.introduce.cn.mapper.SysUserMapper;
import reast.introduce.cn.result.InfoResult;
import reast.introduce.cn.result.loginResult;
import reast.introduce.cn.service.InfoService;
import reast.introduce.cn.util.CreateJwt;
import reast.introduce.cn.vo.InfoVO;
@Service
public class InfoServiceImpl implements InfoService {
@Autowired
private SysUserMapper userMapper;
/**
* 登录接口的逻辑代码
* @param loginDTO
* @return
*/
@Override
public loginResult userlogin(LoginDTO loginDTO) {
SysUser sysUser = new SysUser();
sysUser.setUserName(loginDTO.getUserName());
sysUser.setPassword(loginDTO.getPassword());
if (StringUtils.isEmpty(loginDTO.getUserName())){
return new loginResult(400,"账号不能为空","");
}
if (StringUtils.isEmpty(loginDTO.getPassword())){
return new loginResult(400,"密码不能为空","");
}
//通过登录名查询用户
QueryWrapper<SysUser> wrapper = new QueryWrapper();
wrapper.eq("user_name", loginDTO.getUserName());
SysUser user = userMapper.selectOne(wrapper);
//判断用户是否存在
if (user == null) {
//insert user
userMapper.insert(sysUser);
user = userMapper.selectOne(wrapper);
}
String token = CreateJwt.getoken(sysUser);
//比较密码
if (user.getPassword().equals(loginDTO.getPassword())) {
InfoVO loginVO = new InfoVO();
//这里token直接用一个uuid
//使用jwt的情况下,会生成一个jwt token,jwt token里会包含用户的信息
loginVO.setToken(token);
return new loginResult(200, "登录成功", ""+token);
}
return new loginResult(401,"登录失败","");
}
}
1.12、工具类
1.12.1、CreateJwt
package reast.introduce.cn.util;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import reast.introduce.cn.bean.SysUser;
import java.util.Date;
public class CreateJwt {
public static String getoken(SysUser sysUser) {
//Jwts.builder()生成
//Jwts.parser()验证
JwtBuilder jwtBuilder = Jwts.builder()
.setId(sysUser.getUserId()+"")
.setSubject(sysUser.getUserName()) //用户名
.setIssuedAt(new Date())//登录时间
.signWith(SignatureAlgorithm.HS256, "my-123").setExpiration(new Date(new
Date().getTime()+86400000));
//设置过期时间
//前三个为载荷playload 最后一个为头部 header
System.out.println(jwtBuilder.compact());
return jwtBuilder.compact();
}
}
1.12.2、http上下文
package reast.introduce.cn.util;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @Description: http上下文
*
**/
public class HttpContextUtil {
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
public static String getDomain() {
HttpServletRequest request = getHttpServletRequest();
StringBuffer url = request.getRequestURL();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
}
public static String getOrigin() {
HttpServletRequest request = getHttpServletRequest();
return request.getHeader("Origin");
}
}
1.13、登录VO
package reast.introduce.cn.vo;
;
import lombok.Data;
import reast.introduce.cn.bean.SysUser;
import java.io.Serializable;
/**
* @Description: 登录VO
**/
@Data
public class InfoVO implements Serializable {
private Integer id;
private String token;
//private SysUser sysUser;
}
1.14、主程序类
package reast.introduce;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(value = "reast.introduce.cn.mapper")
public class DatamaskWebApplication {
public static void main(String[] args) {
SpringApplication.run(DatamaskWebApplication.class, args);
}
}
1.15、全局配置
application-dev.yml
spring:
profiles:
active: dev
application-dev.yml
server:
port: 3000
spring:
datasource:
username: root
password: 123456
#url中database为对应的数据库名称
url: jdbc:mysql://localhost:3306/ds_conn?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
type-aliases-package: reast.introduce.cn.bean
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #指定 MyBatis 所用日志的具体实现,未指定时将自动查找
#showSql
logging:
level:
reast.introduce.cn.mapper: debug
1.6、controller层
package reast.introduce.cn.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reast.introduce.cn.dto.LoginDTO;
import reast.introduce.cn.mapper.SysUserMapper;
import reast.introduce.cn.result.loginResult;
import reast.introduce.cn.service.InfoService;
@RestController
@RequestMapping("/api")
public class loginController {
@Autowired
InfoService loginService;
@Autowired
SysUserMapper sysUserMapper;
/**
* TODO 登录接口
* @param loginDTO
* @return
*/
@PostMapping(value = "/login")
@CrossOrigin //后端跨域
public loginResult Userlogin(@RequestBody LoginDTO loginDTO){
return loginService.userlogin(loginDTO);
}
}
2、测试
http://localhost:3000/api/login