springboot搭建增删改查以及创建token
程序员文章站
2022-07-10 17:37:04
...
废话不多说,直接代码:
pom.xml文件如下:
<?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 https://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.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</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>
</dependencies>
<!--<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
实体类如下:
import lombok.Data;
import java.io.Serializable;
@Data
public class Student implements Serializable {
//编号
private Integer id;
//姓名
private String name;
//性别
private String sex;
}
controller如下:
package com.controller;
import com.model.Student;
import com.service.StudentService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @Auther: 澹若水
* @Date: 2020/1/3
* @Description: 学生信息控制器,主要描述了简单的增删改查
*/
@RestController
@RequestMapping(value = "/student")
public class StudentController {
@Resource
StudentService studentService;
/**
* 查找所有学生信息(先从缓存查,如果缓存无再查数据库)
* @return
*/
@GetMapping("/findAll")
public List<Student> findAll() {
return studentService.findAll();
}
/**
* 通过id查找学生信息(先从缓存查,如果缓存无再查数据库)
* @param id
* @return
*/
@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") Integer id) {
return studentService.findById(id);
}
/**
* 通过id删除学生信息,如果缓存有,缓存的也一并删除
* @param id
* @return
*/
@DeleteMapping("/delById/{id}")
public int delById(@PathVariable("id") Integer id) {
return studentService.del(id);
}
/**
* 修改学生信息并更新缓存信息
* @param student
* @return
*/
@PutMapping("/modify")
public int modify(Student student) {
return studentService.modify(student);
}
/**
* 添加学生信息,并给缓存存一份
* @param student
*/
@PostMapping("/save")
public void save(Student student) {
studentService.save(student);
}
}
登录的控制器:
package com.controller;
import com.common.CreateToken;
import com.common.GenerateRandCode;
import com.common.Md5Util;
import com.common.Result;
import com.model.User;
import com.request.LoginRequest;
import com.request.RegUserRequest;
import com.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Auther: 澹若水
* @Date: 2020/1/3
* @Description: 用户登录注册的控制器
*/
@Slf4j
@RestController
@RequestMapping(value = "/login")
public class LoginController {
Map<String, String> map = new HashMap<>();
@Autowired
private UserService userService;
/**
* 用户登录并生成token
*
* @param loginRequest
* @return
*/
@PostMapping(value = "/user/login")
// public Result login(LoginRequest loginRequest, String verificationCode){
public Result login(LoginRequest loginRequest) {
String pwd = Md5Util.inputPassToDBPass(loginRequest.getPassword(), Md5Util.SALT);
loginRequest.setPassword(pwd);
User user = userService.findByNameAndPwd(loginRequest);
// if (!StringUtils.isEmpty(user) && map.get(user.getUserName()).equalsIgnoreCase(verificationCode)) {
if (!StringUtils.isEmpty(user)) {
Map<String, Object> map = new HashMap<>();
map.put("userName", user.getUserName());
//String roleName = userService.findRoleName(user.getUserRole());
// map1.put("roleName", roleName);
String token = CreateToken.createToken(map);
return Result.ok(token);
} else {
return Result.fail(null, "用户不存在!");
}
}
/**
* 生成验证码
*
* @param userName
* @return
*/
@PutMapping("/user/generateCode")
public Map<String, String> generateCode(String userName) {
String verificationCode = GenerateRandCode.RandCode();
if (!map.isEmpty()) {
map.remove(userName);
}
if (StringUtils.isEmpty(verificationCode)) {
log.debug("验证码为空!请输入正确的用户名信息!");
}
map.put(userName, verificationCode);
return map;
}
/**
* 注册用户信息
*
* @param regUserRequest
* @return
*/
@PostMapping(value = "/regUserInfo")
public Result regUserInfo(RegUserRequest regUserRequest) {
String pwd = Md5Util.inputPassToDBPass(regUserRequest.getPassword(), Md5Util.SALT);
regUserRequest.setPassword(pwd);
userService.saveUserInfo(regUserRequest);
return Result.ok("新增用户信息成功!");
}
/**
* 查找所有用户信息
*
* @return
*/
@GetMapping(value = "/findAll")
public Result findAll() {
List<User> list = userService.findAll();
Result result = new Result();
if (list.size() > 0) {
return result.ok(list);
} else {
result.fail(null, "没有查到用户信息!");
}
return result;
}
}
创建token的类:
package com.common;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
/**
* @Author:澹若水
* @Description: 生成token类
* @Date:Created in 2018/12/19
*/
@Slf4j
public class CreateToken {
private static final String SECRET = "JKKLJOoasdlfj";
// token 过期时间: 10天
private static final int CALENDARFIELD = Calendar.DATE;
private static final int CALENDARINTERGERVAL = 10;
/**
* JWT生成Token.
*
* JWT构成: header, payload, signature
*/
public static String createToken(Map<String, Object> map){
Date iatDate = new Date();
Calendar nowTime = Calendar.getInstance();
nowTime.add(CALENDARFIELD, CALENDARINTERGERVAL);
Date expiresDate = nowTime.getTime();
// header Map
String token = JWT.create().withHeader(map) // header
.withIssuedAt(iatDate) // sign time
.withExpiresAt(expiresDate) // expire time
.sign(Algorithm.HMAC256(SECRET)); // signature
return token;
}
/**
* 解密Token
*
* @param token
* @return
*/
public static boolean verifyToken(String token) {
DecodedJWT jwt = null;
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
jwt = verifier.verify(token);
} catch (Exception e) {
System.out.println("token 校验失败, 抛出Token验证非法异常");
}
if (jwt == null) {
return false;
}
return true;
}
}
用户密码加密的工具类:
package com.common;
import org.apache.commons.codec.digest.DigestUtils;
/**
* @Auther: 澹若水
* @Date: 2020/1/3
* @Description: 用于生成MD5 密码的工具类
*/
public class Md5Util {
public static String md5(String input) {
return DigestUtils.md5Hex(input);
}
/*固定盐值*/
public static final String SALT = "1a2b3c4d";
/**
* 第一次md5 :
* <p>
* 用于 通过输入的密码生成 传输的密码 :方法 通过固定盐值和明文密码之间的拼接在生成md5
*
* @param password
* @return
*/
public static String inputPassToFormPass(String password) {
String str = "" + SALT.charAt(5) + SALT.charAt(4) + password + SALT.charAt(3) + SALT.charAt(2);
return md5(str);
}
/**
* 第二次md5 : 通过输入的密码和数据库随机盐值 继续生成 密码
*
* @param input
* @param salt
* @return
*/
public static String formPassToDBPass(String input, String salt) {
String str = "" + salt.charAt(0) + salt.charAt(2) + input + salt.charAt(5) + salt.charAt(4);
return md5(str);
}
/**
* 最终调用生成密码的方法
*/
public static String inputPassToDBPass(String password, String dbsalt) {
String FirstMd5 = inputPassToFormPass(password);
String SecondMd5 = formPassToDBPass(FirstMd5, dbsalt);
return SecondMd5;
}
}
登陆的拦截器:
package com.intercepter;
import com.auth0.jwt.JWT;
import com.common.CreateToken;
import com.model.User;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Auther: 澹若水
* @Date: 2020/1/3
* @Description: 用户登录拦截器,如果token为空直接抛异常
*/
@Component
public class LoginIntercepter implements HandlerInterceptor {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
response.setHeader("Access-Control-Allow-Headers", "token");
// 从 http 请求头中取出 token
String token = request.getHeader("token");
// 如果不是映射到方法直接通过
if (!(object instanceof HandlerMethod)) {
return true;
}
if (StringUtils.isEmpty(token)) {
throw new RuntimeException("token为空,请重新登录!");
}
//获取登陆时存入头部的用户名
String userName = JWT.decode(token).getHeaderClaim("userName").asString();
//获取登陆时存入的角色名
String roleName = JWT.decode(token).getHeaderClaim("roleName").asString();
//获取创建的token的签名
String str = JWT.decode(token).getSignature();
User user = userService.findUserByName(userName);
if (user == null) {
throw new RuntimeException("用户不存在,请重新登录");
}
boolean b = CreateToken.verifyToken(token);
if (b) {
return true;
}
throw new RuntimeException("token无效,请重新输入!");
}
@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 {
}
}
拦截器的配置文件:
package com.intercepter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginIntercepter loginIntercepter;
/**
* 配置拦截器信息,过滤掉登录和注册方法,其余方法都要经过拦截器
* @param registry
*/
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginIntercepter).addPathPatterns("/**").excludePathPatterns("/login/user/login","/login/regUserInfo");
}
}
service接口:
package com.service;
import com.model.Student;
import java.util.List;
public interface StudentService {
/**
* 查询所有
*
* @return
*/
List<Student> findAll();
/**
* 根据id查询学生信息
*
* @param id id
* @return
*/
Student findById(Integer id);
/**
* 根据id删除学生信息
*
* @param id id
* @return
*/
int del(Integer id);
/**
* 修改学生信息
*
* @param student
* @return
*/
int modify(Student student);
/**
* 添加学生信息
*/
void save(Student student);
}
service的实现类:
package com.service.impl;
import com.mapper.StudentMapper;
import com.model.Student;
import com.service.StudentService;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Resource
StudentMapper studentMapper;
@Resource
RedisTemplate redisTemplate;
//Jedis js;
/**
* 查询所有
*
* @return
*/
@Override
public List<Student> findAll() {
//缓存存在
ListOperations<String, Student> operations = redisTemplate.opsForList();
String key = "student";
if (redisTemplate.hasKey(key)) {
return operations.range(key, 0, -1);
} else {
//得到学生集合
List<Student> list = studentMapper.findAll();
operations.leftPushAll(key, list);
return list;
}
}
/**
* 根据id查询学生信息
*
* @param id id
* @return
*/
@Override
public Student findById(Integer id) {
String key = "student_" + id;
ValueOperations<String, Student> operations = redisTemplate.opsForValue();
//缓存存在
if (redisTemplate.hasKey(key)) {
return operations.get(key);
} else {
//得到学生对象
Student student = studentMapper.findById(id);
//添加到缓存
operations.set(key, student);
return student;
}
}
/**
* 根据id删除学生信息
*
* @param id id
* @return
*/
@Override
public int del(Integer id) {
//删除数据库中的数据
int count = studentMapper.del(id);
//缓存存在
String key = "student_" + id;
if (redisTemplate.hasKey(key)) {
//删除对应缓存
redisTemplate.delete(key);
}
return count;
}
/**
* 修改学生信息
*
* @param student
* @return
*/
@Override
public int modify(Student student) {
//修改数据库中的数据
int count = studentMapper.modify(student);
ValueOperations operations = redisTemplate.opsForValue();
//缓存存在
String key = "student_" + student.getId();
if (redisTemplate.hasKey(key)) {
//更新缓存
Student stu = studentMapper.findById(student.getId());
operations.set(key, stu);
}
return count;
}
@Override
public void save(Student student) {
studentMapper.save(student);
ValueOperations operations = redisTemplate.opsForValue();
operations.set("student_" + student.getId(),student);
}
}
mapper文件:
package com.mapper;
import com.model.Student;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface StudentMapper {
/**
* 查询所有
*
* @return
*/
@Select("select * from student")
List<Student> findAll();
/**
* 根据id查询学生信息
*
* @param id id
* @return
*/
@Select("select * from student where id=#{id}")
Student findById(Integer id);
/**
* 根据id删除学生信息
*
* @param id id
* @return
*/
@Delete("delete from student where id =#{id}")
int del(Integer id);
/**
* 修改学生信息
*
* @param student
* @return
*/
@Update("update student set name =#{name},sex=#{sex} where id=#{id}")
int modify(Student student);
/**
* 添加学生信息
*/
@Insert("insert into student(name,sex) values(#{name},#{sex})")
void save(Student student);
}
最后是配置文件:
redis.ip= 192.168.0.101 ## redis所在的服务器IP
redis.port=6379
#数据源配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
#在下面3306配置自己的数据库(自己配置)
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai
#数据库用户(自己配置)
spring.datasource.username=root
#数据库密码(自己配置)
spring.datasource.password=root
spring.datasource.initialSize=20
spring.datasource.minIdle=50
spring.datasource.maxActive=500
## Mybatis 配置
# 配置为 com.pancm.bean 指向实体类包路径。
mybatis.typeAliasesPackage=com.model
redis和数据库是我本地的,根据不同可以修改成自己的。以上就是最简单的一套增删改查了。
上一篇: 工厂模式之简单工厂模式
下一篇: 设计模式漫谈之外观模式